EXPLAINING ISTANBUL HOUSING PRICE WITH ECONOMIC INDICATORS & FORECASTING UNIT PRICES CHANGE





Alparslan YARIKTAS

516171003




0.0.1 Introduction

0.0.1.1 Problem Question

  1. How The Economic Indicators Affect on Housing Unit Price at Istanbul?
  2. Which indicators more dominant on the prices?
  3. What is the equation for Istanbul Unit Housing Price?
  4. What will be the housing price for 6 months?

0.0.1.2 Literature Review

  • The construction industry and other related sub industries are the most crucial aspects of the economy The Turkish housing industry has achieved fast growth in the past fifteen years The macroeconomic importance of the construction industry arises from its multiplier effect It sets 250 sub industries in motion with impacts on both growth and employment.

  • Housing and related interests make up a significant portion of the construction industry in our country. The industry’s growth rate is influenced by booms/stagnation observed in housing demand and sales. The industry’s sensitivity to the total national growth is also high.

  • As well the price of a home in the housing sector is determined by the balance of housing supply and demand In the short term, the supply of housing is for the most part fixed, meaning that the main variable in determining housing prices is the rise or decline in demand Consequently, in the short term, rising demand for housing causes prices to increase and declining demand causes them to fall. 



In this study Section - 1 includes “The Regression Analysis” to explain the dependent variable which is Unit Housing Price in Istanbul with independent variables below in the table and tried to find the highest and most effective model that explaining unit housing price. In Section B, “The ARIMA Analysis” used for forecasting the “Housing Price Changes In Istanbul” for six months. The summary of study as in the below following chart.

Section 1 - Cross Section Section 2 - Time Series
Regression Analysis Auto Regressive Integrated Moving Average Analysis
Explaining Istanbul Housing Unit Price Forecasting Istanbul Housing Price’s Change Next Month

Some variables and description in the below chart.

VARIABLES DESCRIPTION
DATE Monthly Date from 2013 to 2019
IST_RPPI Istanbul Residential Property Price Index
IST_PRC Istanbul Housing Unit Price TL/m²
IST_CNST_PRMT Construction Permits
IST_OCCP_PRMT Occupational Permits
MG_RT Mortgage Credit Rates
IST_FGR_SL Istanbul Housing Sales to Only Foreigners
IST_PRP_SL Istanbul Total Housing Sales
IST_MRTG_SL Istanbul Housing Sales by Using Mortgage Loan
CNSTR_TRST Construction Trust Index
IST_CPI Istanbul Consumer Price Index
TR_PPI Turkey Producer Price Index
USD_RT USD Buying Exchange Rate
RNT_CPI IST Rent Consumer Price Index
NEMP_RT Unemployment Rate

Notes : IST_CNST_PRMT - IST_OCCP_PRMT forward some different periods 2,3,4,6,9 etc.





For the reason why using both Price Index and Unit Prices main purpose of the using both Price Index and Prices on the data set in order to see the correlation between Monthly Property Price Index and Unit Prices and cross check our observations.
It can easily expect the correlation coefficient aproximately ~ 99%
The main value of Housing Prices Index and Unit Prices would be the expecting correlation coefficient which is approximately 0.96 but the monthly percentage changes between them wouldn’t be the bigger than 80%.
This study also prove this on the next paragraphs.

0.0.2 Cross Section

0.0.2.1 Setting The Libraries

Before start the study, the libraries should be import to get rid of the errors and help to analyze all in one for study.

library(readr)
library(ggplot2)
library(mlbench)
library(corrplot)
library(Amelia)
library(caret)
library(plotly)
library(caTools)
library(reshape2)
library(dplyr)
library(knitr)
library(ggplot2)
library(forecast)
library(tseries)
library(astsa)
library(readr)

0.0.2.2 Data Import

This project include different studies that divide main values and percentage change according to the previous months.

IST_RPPI_MODEL IST_RPPI_MODEL_CG
Main Value of All variables Monthly Percentage Changes Values(%)


library(readr)
IST_RPPI_MODEL <- read_csv("IST_RPPI_MODEL.csv", 
                           col_types = cols(DATE = col_date(format = "%d.%m.%Y")))
IST_RPPI_MODEL_CG <- read_csv("IST_RPPI_MODEL_CG.csv", 
                              col_types = cols(DATE = col_date(format = "%d.%m.%Y")))
#View(IST_RPPI_MODEL)
#View(IST_RPPI_MODEL_CG)

0.0.2.3 Data Type Observation

All the variables according to data type is “dbl” that is related with numeric values except “Date”.
The study is not going to include dates in any model at Section-1 on Regression Analysis. Seeing the data types and first 5 column is also important for the data set what imported correctly.

head(IST_RPPI_MODEL)
#str(IST_RPPI_MODEL) - to see the data type
#for the other dataset 
#str(IST_RPPI_MODEL_CG)

0.0.2.4 Understanding Data 

In order to understand and examine data generally use five number summary.
Five Number Summary shows median, mean, min-max and Q1 & Q3 values.
This may help us to mining and eliminating and understanding the structure of data and classifying the observations.
For example :

  • Housing Unit Prices in Istanbul has minimum value which is 2064 ; Mean Value is 3708 and also the Median Value is 3922. Q3 is 4562 and Max. value 5123. It can be easily understanding this data classified with a good range because there is not any extreme observation.

  • Istanbul Unit Price Changes min.value -1.266, max.value 3.756, mean 1.285, median 1.366

  • Total Istanbul Housing Sales min.value 11903, max.value 27156, mean value 19512, median value 19305. 3rd Quartile value is 21213 This value shows us there is not any extreme circumstances.

  • When it comes to mortgage rates,

Min. 1st Q. Median Mean 3rd Q. Max.
8.30 11.00 12.20 13.11 13.93 28.99


The situation about the outliers will be scrutinized next paragraphs.

  1. Unit Housing Price
summary(IST_RPPI_MODEL$IST_PRC)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   2064    2775    3922    3708    4562    5123 
  1. Residential Housing Price Index
summary(IST_RPPI_MODEL$IST_RPPI)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  47.81   63.26   86.48   81.55  100.39  103.19 
  1. Property Sales
summary(IST_RPPI_MODEL$IST_PRP_SL)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  11903   17398   19305   19512   21213   27156 
  1. Foreigner Sales
summary(IST_RPPI_MODEL$IST_FGR_SL)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  120.0   403.2   540.5   608.1   646.0  2283.0 
  1. Sales by Mortgage
summary(IST_RPPI_MODEL$IST_MRTG_SL)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    987    6230    7150    7109    8672   10805 
  1. Occupational Permits forward 9 months
summary(IST_RPPI_MODEL$IST_OCCP_PT_9)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  552.0   966.2  1121.5  1147.3  1318.5  2024.0 
  1. Consumer Price Index
summary(IST_RPPI_MODEL$IST_CPI)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  220.9   248.1   278.4   285.7   316.6   403.7 
  1. Mortgage Rates
summary(IST_RPPI_MODEL$MG_RT)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   8.30   11.00   12.20   13.11   13.93   28.99 
  1. Construction Permits
summary(IST_RPPI_MODEL$IST_CNST_PT)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  322.0   967.8  1322.5  1371.3  1597.0  4845.0 
  1. Rent Consumer Price Index
summary(IST_RPPI_MODEL$RNT_CPI)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  297.5   327.1   366.3   373.8   415.1   477.5 
  1. Turkey Producer Price Index
summary(IST_RPPI_MODEL$TR_PPI)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  206.7   234.6   250.9   271.8   296.1   443.8 
  1. USD Currency Rates
summary(IST_RPPI_MODEL$USD_RT)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.770   2.217   2.920   3.055   3.663   6.380 
#summary(IST_RPPI_MODEL)


#summary(IST_RPPI_MODEL_CG)
#summary(IST_RPPI_MODEL_CG$IST_RPPI)
#summary(IST_RPPI_MODEL_CG$IST_FGR_SL)
#summary(IST_RPPI_MODEL_CG$IST_MRTG_SL)
#summary(IST_RPPI_MODEL_CG$IST_OCCP_PT_9)
#summary(IST_RPPI_MODEL_CG$IST_CPI)
#summary(IST_RPPI_MODEL_CG$MG_RT)


The values with box plot In addition to numeric table, Housing Sales also be showed with box plot.

boxplot(IST_RPPI_MODEL$IST_PRC, main = "Housing Prices",
        sub=paste("Outlier rows:  ", boxplot.stats(IST_RPPI_MODEL$IST_PRC)$out))

boxplot(IST_RPPI_MODEL$IST_MRTG_SL, main = "Housing Sales By Using Loan", 
        border = par("fg"), 
        sub=paste("Outlier Rows:  ", boxplot.stats(IST_RPPI_MODEL$IST_MRTG_SL)$out))

boxplot(IST_RPPI_MODEL$MG_RT, main = "Mortgage Rates",
        sub=paste("Outlier Rows:  ", boxplot.stats(IST_RPPI_MODEL$MG_RT)$out))

boxplot(IST_RPPI_MODEL$IST_RPPI, main = "Property Price Index",
        sub=paste("Outlier Rows:  ", boxplot.stats(IST_RPPI_MODEL$IST_RPPI)$out))

boxplot(IST_RPPI_MODEL$IST_FGR_SL, main = "Foreigner Sales",
        sub=paste("Outlier Rows:  ", boxplot.stats(IST_RPPI_MODEL$IST_FGR_SL)$out))

boxplot(IST_RPPI_MODEL$IST_OCCP_PT_9, main = "Occupational Permits forward 9 months",
        sub=paste("Outlier Rows:  ", boxplot.stats(IST_RPPI_MODEL$IST_OCCP_PT_9)$out))

boxplot(IST_RPPI_MODEL$USD_RT, main = "USD Exchange Rate",
        sub=paste("Outlier Rows:  ", boxplot.stats(IST_RPPI_MODEL$USD_RT)$out))

boxplot(IST_RPPI_MODEL$RNT_CPI, main = "Rent Consumer Price Index",
        sub=paste("Outlier Rows:  ", boxplot.stats(IST_RPPI_MODEL$RNT_CPI)$out))

MG_RT_OUT <- boxplot.stats(IST_RPPI_MODEL$MG_RT)$out
MRTG_SL_OUT <- boxplot.stats(IST_RPPI_MODEL$IST_MRTG_SL)$out
data.frame(MG_RT_OUT, MRTG_SL_OUT)
IST_FGR_SL_OUT <- boxplot.stats(IST_RPPI_MODEL$IST_FGR_SL)$out
IST_OCCP_PT_9_OUT <- boxplot.stats(IST_RPPI_MODEL$IST_OCCP_PT_9)$out
USD_RT_OUT <- boxplot.stats(IST_RPPI_MODEL$USD_RT)$out
data.frame(IST_FGR_SL_OUT, IST_OCCP_PT_9_OUT, USD_RT_OUT)


Mortgage Rates and Mortgage Sales have 5 outliers, Foreigner Sales 6, Occupational permits 1 and 2 outliers in Usd Exchange Rates.

The outliers distracting model confidence, otliers should remove from dataset. In the study outliers used because of the size.

An Alternative solution may offer remove the outliers and fill with median value of column.

When It comes to dependent - independent variables, It can be easily showing distribution in scatter plot.

For example :

Some distrubitons about Housing Price and other variables showing with the scatter plot.

scatter.smooth(x = IST_RPPI_MODEL$MG_RT, 
               y = IST_RPPI_MODEL$IST_PRC, 
               main = "Housing Price ~ Mortgage Rates")

scatter.smooth(x = IST_RPPI_MODEL$IST_PRP_SL, 
               y = IST_RPPI_MODEL$IST_PRC, 
               main = "Housing Price ~ Housing Sales")

scatter.smooth(x = IST_RPPI_MODEL$RNT_CPI, 
               y = IST_RPPI_MODEL$IST_PRC, 
               main = "Housing Price ~ Rent Price Index")

  • This plot also sort out to correlation.
  • The relation between price & mortgage rates also positive correlation but taking into consideration that supply and demand equilibrium, expecting when mortgage rates down prices would be higher because of the demand would increasing.
  • When it comes to Turkey considering that there is an imbalance situation. People always wanting to get a housing neither mortgage rates increase nor mortgage rates decrease.
  • The study emphasis this situation on next paragraphs at the Correlation.

In order to see the missing observations, easily get this code by using Amelia Package. In this study, any missing value the model including.

0.0.2.5 See The Missing Values 

# in order to see the sum of missing values
# colSums(is.na(IST_RPPI_MODEL))
# for show the plot of the missing values
missmap(IST_RPPI_MODEL, col=c('red', 'green'), 
        y.at=1, y.labels = '', legend = TRUE)
the condition has length > 1 and only the first element will be usedUnknown or uninitialised column: 'arguments'.Unknown or uninitialised column: 'arguments'.

# missmap(IST_RPPI_MODEL_CG, col=c('red', 'green'), y.at=1, y.labels = '', legend = TRUE)
# to fill the median value if the missing values were in dataset
# IST_RPPI_MODEL$...[is.na(IST_RPPI_MODEL$...)] <- median(IST_RPPI_MODEL$..., na.rm = TRUE)

Note: The study doesn’t consist any missing observations. On the some literature text that filling the missing values with median value of the variables.

0.0.2.6 Show The Correlation

Correlation table including related coefficients below in the chart.

# coefficients tables
res_mn <- cor(select(IST_RPPI_MODEL, -DATE))
res_mn <- data.frame(round(res_mn, 2))
head(res_mn, n=6)

This table show us the correlation coefficients between Istanbul Unit Housing Prices and the other variables.
The best correlation equivalent in order to explain the housing unit prices :

  1. RNT_CPI : 0.96

  2. IST_CPI : 0.93

  3. USD_RT : 0.88

  4. TR_PPI : 0.83

  5. NEMP_RT : 0.64

  6. IST_FGR_SL : 0.64

  7. MG_RT : 0.59

  8. IST_MRTG_SL : -0.55

  9. IST_OCCP_PT_9 : 0.44

  10. CNSTR_TRST : -0.37

  11. IST_CNST_PT : -0.16

The Index which are Rent Consumer Price Index, Istanbul Consumer Price Index, USD Rate and Turkey Producer Price Index affecting The Housing Unit Prices very strongly correlated. So that try to find the best model in this study, include strong correlated variables in the model on next paragraphs.

res_cg<- cor(select(IST_RPPI_MODEL_CG, -DATE))
res_cg <- data.frame(round(res_cg, 2))
head(res_cg, n=1)

This study also proved that the marker of Price and Price Index is positive correlated but first case Unit Price and Price Index correlated equal, The correlation coefficient between Unit Price Changes and Property Price Index Changes nearly 0.62, different from each others.

## plot the correlations
corrplot(cor(select(IST_RPPI_MODEL, -DATE)), 
         method = "square", type = "upper", sig.level = .01)

#corrplot(cor(select(IST_RPPI_MODEL_CG, -DATE)), 
#         method = "square", addrect = 2, sig.level = .01, type #= "upper")
  1. The main value’s correlation coefficient was ~ 1.00 but in this case the monthly changes different than each others when considered the actual values, the monthly change’s coefficients different from main values. First, we look up the Unit Price and Property Price Index’s coefficient is approximately ~ 100% but we look the monthly change of the both variables coefficient is ~62%, So when we consider why the monthly changes different than main values.

This two main dependent variables is the same. It can be explained that Price Index is publishing after The Unit Prices maybe 1-2 month, Price Index can be influenced by the other things. According to housing market the index publishing after 1 and 2 months published unit prices and Index be affecting from other main Index like Rent, CPI, PPI etc.

  1. Secondly, we should look the Construction-Occupational Permits the best correlation with Housing Prices is
  • The direct and not postponed value of Construction Permits ~ -16%
  • Held over value for 9 months of Occupational Permits ~ 44%

So, It would be think that when a construction start and all permits be get , how long will this pre-construction and construction process extend or when this new supply get in the market? The study also show that Housing Market Prices, much more influenced by Occupational Permits which published data forward for 9 months.

0.0.2.7 Showing The Density

ggplotly(IST_RPPI_MODEL %>%
             ggplot(aes(IST_PRC)) +
             stat_density() +
             theme_light())
ggplotly(IST_RPPI_MODEL_CG%>%
             ggplot(aes(IST_PRC)) +
             stat_density() +
             theme_light())

The Property Price has two major range -bimodal distribution- one of the between 55-60, the other is 95-100 because of the time process .
Prices always getting increase time to time and also the monthly price changes have one modal distribution. It can be easily reach mod, median, mean values show in “Five Number Summary section”.

Istanbul Housing Price monthly change has one modal,normal distribution. Showing The Five Number Summary of Price and Price Change belowing chart.

summary(IST_RPPI_MODEL$IST_PRC)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   2064    2775    3922    3708    4562    5123 
summary(IST_RPPI_MODEL_CG$IST_PRC)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 -1.266   0.463   1.336   1.285   2.084   3.758 

0.0.2.8 Seeing The Correlation Plot

In order to plot all variables related with the Housing Prices :

IST_RPPI_MODEL %>%
    select(c(IST_PRC, MG_RT, IST_FGR_SL, IST_PRP_SL, 
             IST_MRTG_SL, CNSTR_TRST, RNT_CPI, 
             IST_CPI, TR_PPI, USD_RT, 
             NEMP_RT, IST_CNST_PT, IST_OCCP_PT_9)) %>%
    melt(id.vars = "IST_PRC") %>%
    ggplot(aes(x = value, y = IST_PRC, colour = variable)) +
    geom_point(alpha = 0.7) +
    stat_smooth(aes(colour = "black")) +
    facet_wrap(~ variable, scales = "free", ncol = 3) +
    labs(x = "Variable Value", 
         y = "Istanbul Housing Price") +
    theme_minimal()

#IST_RPPI_MODEL_CG %>%
#    select(c(IST_PRC, MG_RT, IST_FGR_SL, 
#    IST_PRP_SL, IST_MRTG_SL, CNSTR_TRST, 
#    RNT_CPI, IST_CPI, TR_PPI, USD_RT, 
#    NEMP_RT, IST_CNST_PT, IST_OCCP_PT_9)) %>%
#    melt(id.vars = "IST_PRC") %>%
#    ggplot(aes(x = value, y = IST_PRC, colour = variable)) +
#    geom_point(alpha = 0.7) +
#    stat_smooth(aes(colour = "black")) +
#    facet_wrap(~ variable, scales = "free", ncol = 3) +
#    labs(x = "Variable Value",
#    y = "Istanbul Housing Price Change") +
#    theme_minimal()

The correlation between all variables Positive & Negative Correlation would easily showed above a plot with Istanbul Housing Prices.

Positive Corelation Negative Correlation
Mortgage Rates Construction Trust Index
Foreigner Sales Mortgage Sales
Rent CPI
USD Rate
TR PPI
IST CPI
NEMP Rate


UNEMP rate is also expecting negative correlation because the purchasing power is decreasing so anyone would not want to buy a house this means demand will decrease and price should be expecting down. In this case this not go through what we expecting.

0.0.2.9 Building A Model (Train-Test)

0.0.2.9.1 Setting a Seed Random Number

Seed number should be selected to determine the same results, accuracy, errors every run command. In this study, 2019 is specified.

#set.seed(2019)
#split <- sample.split(IST_RPPI_MODEL, SplitRatio = 0.70)
#train_mn <- subset(IST_RPPI_MODEL, split == FALSE)
#test_mn  <- subset(IST_RPPI_MODEL, split == FALSE)
#set.seed(2019)
#split <- sample.split(IST_RPPI_MODEL_CG, SplitRatio = 0.70)
#train_cg <- subset(IST_RPPI_MODEL_CG, split == TRUE)
#test_cg  <- subset(IST_RPPI_MODEL_CG, split == FALSE)

Split is meaning the portion of the training data. For a study train set determined 0.70 of all data set this should be increase in small data sets as well test set specified 0.30
Notes : Split and seed number didn’t use for the model why the model is weak for observations ~ 72

0.0.2.9.2 Building Different Models and See Residuals 
model1_mn <- lm(IST_PRC ~ MG_RT + IST_FGR_SL +  
                    IST_MRTG_SL + CNSTR_TRST +
                    RNT_CPI + USD_RT + 
                    IST_CNST_PT +  IST_OCCP_PT_9 , 
                data = IST_RPPI_MODEL)
summary(model1_mn)

Call:
lm(formula = IST_PRC ~ MG_RT + IST_FGR_SL + IST_MRTG_SL + CNSTR_TRST + 
    RNT_CPI + USD_RT + IST_CNST_PT + IST_OCCP_PT_9, data = IST_RPPI_MODEL)

Residuals:
    Min      1Q  Median      3Q     Max 
-474.41 -183.41  -54.82  173.76  450.79 

Coefficients:
                Estimate Std. Error t value Pr(>|t|)    
(Intercept)   -4.953e+03  7.345e+02  -6.743  5.6e-09 ***
MG_RT          2.651e+01  2.520e+01   1.052    0.297    
IST_FGR_SL    -1.726e-01  2.013e-01  -0.858    0.394    
IST_MRTG_SL    3.880e-02  2.880e-02   1.347    0.183    
CNSTR_TRST     3.926e+00  4.885e+00   0.804    0.425    
RNT_CPI        2.169e+01  1.901e+00  11.414  < 2e-16 ***
USD_RT        -1.857e+02  1.159e+02  -1.603    0.114    
IST_CNST_PT    7.382e-02  4.622e-02   1.597    0.115    
IST_OCCP_PT_9  1.591e-01  1.215e-01   1.310    0.195    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 232.7 on 63 degrees of freedom
Multiple R-squared:  0.9483,    Adjusted R-squared:  0.9417 
F-statistic: 144.4 on 8 and 63 DF,  p-value: < 2.2e-16

Model’s P-values not good what expecting, Model-1 says us only Rent CPI is affecting Price, The data including both one digit numbers and four&five digit numbers. An alternative solution to get rid of big numbers to start logarithm process for big numbers.
Built a new one more model which is Model-2 with logarithm process.

model2_mn <- lm(log10(IST_PRC) ~ MG_RT + log10(IST_FGR_SL) +  
                    log10(IST_MRTG_SL) + CNSTR_TRST + RNT_CPI + USD_RT + 
                    log10(IST_CNST_PT) +  log10(IST_OCCP_PT_9) , 
                data = IST_RPPI_MODEL)
summary(model2_mn)

Call:
lm(formula = log10(IST_PRC) ~ MG_RT + log10(IST_FGR_SL) + log10(IST_MRTG_SL) + 
    CNSTR_TRST + RNT_CPI + USD_RT + log10(IST_CNST_PT) + log10(IST_OCCP_PT_9), 
    data = IST_RPPI_MODEL)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.077355 -0.026468 -0.003827  0.024054  0.083776 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)           1.8108140  0.2877130   6.294 3.34e-08 ***
MG_RT                 0.0006012  0.0035592   0.169   0.8664    
log10(IST_FGR_SL)     0.0738485  0.0331655   2.227   0.0296 *  
log10(IST_MRTG_SL)    0.0595833  0.0620361   0.960   0.3405    
CNSTR_TRST            0.0005521  0.0007025   0.786   0.4349    
RNT_CPI               0.0026682  0.0002929   9.110 4.17e-13 ***
USD_RT               -0.0322541  0.0169629  -1.901   0.0618 .  
log10(IST_CNST_PT)    0.0560448  0.0250875   2.234   0.0290 *  
log10(IST_OCCP_PT_9)  0.0624600  0.0476259   1.311   0.1945    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.03452 on 63 degrees of freedom
Multiple R-squared:  0.9298,    Adjusted R-squared:  0.9208 
F-statistic: 104.2 on 8 and 63 DF,  p-value: < 2.2e-16

Model-2 increased the p-value of variables. When looking model-2, there are four different variables in confidence p-values as well USD Rate close to line.
In Model-2 used logarithm on three or more digit values.

model3_mn <- lm(log10(IST_PRC) ~ log10(MG_RT) + log10(IST_FGR_SL) +  
                    log10(IST_MRTG_SL) + log10(CNSTR_TRST) + 
                    log10(RNT_CPI) + log10(USD_RT) + 
                    log10(IST_CNST_PT)  , 
                data = IST_RPPI_MODEL)
summary(model3_mn)

Call:
lm(formula = log10(IST_PRC) ~ log10(MG_RT) + log10(IST_FGR_SL) + 
    log10(IST_MRTG_SL) + log10(CNSTR_TRST) + log10(RNT_CPI) + 
    log10(USD_RT) + log10(IST_CNST_PT), data = IST_RPPI_MODEL)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.059546 -0.021530 -0.001008  0.017957  0.082533 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        -2.45896    0.69953  -3.515 0.000813 ***
log10(MG_RT)        0.17492    0.11004   1.590 0.116859    
log10(IST_FGR_SL)   0.02709    0.02995   0.905 0.369053    
log10(IST_MRTG_SL)  0.13435    0.05131   2.618 0.011015 *  
log10(CNSTR_TRST)   0.09797    0.09546   1.026 0.308622    
log10(RNT_CPI)      1.89303    0.29121   6.501 1.39e-08 ***
log10(USD_RT)       0.03683    0.14308   0.257 0.797697    
log10(IST_CNST_PT)  0.05401    0.02128   2.539 0.013571 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.02972 on 64 degrees of freedom
Multiple R-squared:  0.9471,    Adjusted R-squared:  0.9413 
F-statistic: 163.8 on 7 and 64 DF,  p-value: < 2.2e-16

In Model-3, all variables reduced with logarithm so that decrease digits but in this model there isn’t enough confidence than Model-2. So keep continuous with Model-2 and remove the highest p-value which is mortgage rates plus mortgage sales. Add the property sales rather than mortgage sales.

model4_mn <- lm(log10(IST_PRC) ~ log10(IST_FGR_SL) +  
                    log10(IST_PRP_SL) + CNSTR_TRST + RNT_CPI + USD_RT + 
                    log10(IST_CNST_PT) +  log10(IST_OCCP_PT_9) , 
                data = IST_RPPI_MODEL)
summary(model4_mn)

Call:
lm(formula = log10(IST_PRC) ~ log10(IST_FGR_SL) + log10(IST_PRP_SL) + 
    CNSTR_TRST + RNT_CPI + USD_RT + log10(IST_CNST_PT) + log10(IST_OCCP_PT_9), 
    data = IST_RPPI_MODEL)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.079379 -0.023790 -0.006316  0.029584  0.051114 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)           2.4238074  0.3063565   7.912 4.61e-11 ***
log10(IST_FGR_SL)     0.0867433  0.0294176   2.949  0.00445 ** 
log10(IST_PRP_SL)    -0.1132032  0.0668606  -1.693  0.09530 .  
CNSTR_TRST            0.0007370  0.0006209   1.187  0.23957    
RNT_CPI               0.0027436  0.0002770   9.904 1.54e-14 ***
USD_RT               -0.0413958  0.0152992  -2.706  0.00872 ** 
log10(IST_CNST_PT)    0.0719461  0.0244949   2.937  0.00460 ** 
log10(IST_OCCP_PT_9)  0.0652729  0.0461248   1.415  0.16188    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.03394 on 64 degrees of freedom
Multiple R-squared:  0.931, Adjusted R-squared:  0.9235 
F-statistic: 123.4 on 7 and 64 DF,  p-value: < 2.2e-16

When considered the Construction Trust Index’s p-value so higher than others. It can be remove from model, try to find more accuracy model in Model-5.

model5_mn <- lm(log10(IST_PRC) ~ log10(IST_FGR_SL) +  
                    log10(IST_PRP_SL)  + RNT_CPI + USD_RT + 
                    log10(IST_CNST_PT) +  log10(IST_OCCP_PT_9) , 
                data = IST_RPPI_MODEL)
summary(model5_mn)

Call:
lm(formula = log10(IST_PRC) ~ log10(IST_FGR_SL) + log10(IST_PRP_SL) + 
    RNT_CPI + USD_RT + log10(IST_CNST_PT) + log10(IST_OCCP_PT_9), 
    data = IST_RPPI_MODEL)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.083918 -0.024270 -0.006217  0.031252  0.051470 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)           2.5382655  0.2917025   8.702 1.66e-12 ***
log10(IST_FGR_SL)     0.0804707  0.0290301   2.772 0.007260 ** 
log10(IST_PRP_SL)    -0.1238142  0.0664687  -1.863 0.067018 .  
RNT_CPI               0.0028985  0.0002451  11.824  < 2e-16 ***
USD_RT               -0.0500706  0.0134835  -3.713 0.000427 ***
log10(IST_CNST_PT)    0.0801521  0.0235731   3.400 0.001156 ** 
log10(IST_OCCP_PT_9)  0.0490817  0.0442006   1.110 0.270905    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.03404 on 65 degrees of freedom
Multiple R-squared:  0.9295,    Adjusted R-squared:  0.923 
F-statistic: 142.9 on 6 and 65 DF,  p-value: < 2.2e-16

Model-5 good correlated to explain the prices but It is not enough because of the big p-values. In model-6, get rid of the Occupational Permits.

model6_mn <- lm(log10(IST_PRC) ~ log10(IST_FGR_SL) +  
                    log10(IST_PRP_SL)  + RNT_CPI + USD_RT + 
                    log10(IST_CNST_PT)  , 
                data = IST_RPPI_MODEL)
summary(model6_mn)

Call:
lm(formula = log10(IST_PRC) ~ log10(IST_FGR_SL) + log10(IST_PRP_SL) + 
    RNT_CPI + USD_RT + log10(IST_CNST_PT), data = IST_RPPI_MODEL)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.07949 -0.02566 -0.00592  0.03070  0.05494 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)         2.6541108  0.2728896   9.726 2.27e-14 ***
log10(IST_FGR_SL)   0.0888126  0.0280907   3.162 0.002370 ** 
log10(IST_PRP_SL)  -0.1250391  0.0665768  -1.878 0.064784 .  
RNT_CPI             0.0029514  0.0002409  12.253  < 2e-16 ***
USD_RT             -0.0522155  0.0133680  -3.906 0.000223 ***
log10(IST_CNST_PT)  0.0811789  0.0235965   3.440 0.001012 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.0341 on 66 degrees of freedom
Multiple R-squared:  0.9282,    Adjusted R-squared:  0.9227 
F-statistic: 170.6 on 5 and 66 DF,  p-value: < 2.2e-16

When Supply-Demand Equilibrium considered: Property Sales expecting increase, Price would be get higher. Because of the confidence level of Property Sales the variable’s marker say us the negative situation. In Model-7, removed the Property Sales.

model7_mn <- lm(log10(IST_PRC) ~ log10(IST_FGR_SL) +  
                    RNT_CPI + USD_RT + 
                    log10(IST_CNST_PT)  , 
                data = IST_RPPI_MODEL)
summary(model7_mn)

Call:
lm(formula = log10(IST_PRC) ~ log10(IST_FGR_SL) + RNT_CPI + USD_RT + 
    log10(IST_CNST_PT), data = IST_RPPI_MODEL)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.083967 -0.027947 -0.005618  0.030005  0.069826 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)         2.1745802  0.0981212  22.162  < 2e-16 ***
log10(IST_FGR_SL)   0.0722039  0.0271606   2.658 0.009810 ** 
RNT_CPI             0.0029860  0.0002447  12.204  < 2e-16 ***
USD_RT             -0.0521542  0.0136177  -3.830 0.000285 ***
log10(IST_CNST_PT)  0.0732571  0.0236503   3.098 0.002850 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.03474 on 67 degrees of freedom
Multiple R-squared:  0.9243,    Adjusted R-squared:  0.9198 
F-statistic: 204.7 on 4 and 67 DF,  p-value: < 2.2e-16

Model-7 is final outcome in which more comprehensive and meaningfully than other models. The model prove that :

  • If Total Foreigner Sale increase than Price would be higher
  • If Rent Consumer Price Index would be higher than Price get increase
  • When it come to USD Rate, considered the Housing Market at this moment. USD currency extremely high and Housing Prices getting decrease. So this model actually prove that.
  • Construction Permits affecting housing prices positive.

  • Another different model for explaining Mortgage Sales :

model8_mn <- lm(log10(IST_MRTG_SL) ~ MG_RT + log10(IST_FGR_SL) + 
                    log10(IST_PRC) + IST_RPPI +
                    CNSTR_TRST + RNT_CPI + IST_CPI + 
                    TR_PPI + USD_RT + NEMP_RT + 
                    log10(IST_CNST_PT) +  
                    log10(IST_OCCP_PT_9) , 
                data = IST_RPPI_MODEL)
summary(model8_mn)

Call:
lm(formula = log10(IST_MRTG_SL) ~ MG_RT + log10(IST_FGR_SL) + 
    log10(IST_PRC) + IST_RPPI + CNSTR_TRST + RNT_CPI + IST_CPI + 
    TR_PPI + USD_RT + NEMP_RT + log10(IST_CNST_PT) + log10(IST_OCCP_PT_9), 
    data = IST_RPPI_MODEL)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.169169 -0.023805 -0.000374  0.046476  0.182193 

Coefficients:
                      Estimate Std. Error t value Pr(>|t|)    
(Intercept)           7.039615   3.320589   2.120  0.03822 *  
MG_RT                -0.046521   0.006010  -7.740  1.5e-10 ***
log10(IST_FGR_SL)     0.107414   0.080741   1.330  0.18852    
log10(IST_PRC)       -1.037223   1.043871  -0.994  0.32446    
IST_RPPI              0.004044   0.009811   0.412  0.68167    
CNSTR_TRST           -0.001159   0.001750  -0.662  0.51025    
RNT_CPI              -0.006574   0.003119  -2.108  0.03928 *  
IST_CPI               0.015465   0.005552   2.786  0.00717 ** 
TR_PPI               -0.006651   0.003196  -2.081  0.04180 *  
USD_RT                0.019703   0.065725   0.300  0.76540    
NEMP_RT              -0.017519   0.013246  -1.323  0.19107    
log10(IST_CNST_PT)    0.062833   0.056462   1.113  0.27029    
log10(IST_OCCP_PT_9)  0.106697   0.103936   1.027  0.30881    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.06588 on 59 degrees of freedom
Multiple R-squared:  0.8997,    Adjusted R-squared:  0.8793 
F-statistic:  44.1 on 12 and 59 DF,  p-value: < 2.2e-16

The model can’t explain what the study want. Remove the high p-values which are IST_RPPI and CNSTR_TRST from model.

model9_mn <- lm(log10(IST_MRTG_SL) ~ MG_RT + log10(IST_FGR_SL) + 
                    log10(IST_PRC) + 
                    RNT_CPI + IST_CPI + 
                    TR_PPI + USD_RT + NEMP_RT + 
                    log10(IST_CNST_PT) +  
                    log10(IST_OCCP_PT_9) , 
                data = IST_RPPI_MODEL)
summary(model9_mn)

Call:
lm(formula = log10(IST_MRTG_SL) ~ MG_RT + log10(IST_FGR_SL) + 
    log10(IST_PRC) + RNT_CPI + IST_CPI + TR_PPI + USD_RT + NEMP_RT + 
    log10(IST_CNST_PT) + log10(IST_OCCP_PT_9), data = IST_RPPI_MODEL)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.178090 -0.027195 -0.001252  0.040338  0.189463 

Coefficients:
                      Estimate Std. Error t value Pr(>|t|)    
(Intercept)           5.804990   1.307289   4.440 3.84e-05 ***
MG_RT                -0.044687   0.005255  -8.504 6.00e-12 ***
log10(IST_FGR_SL)     0.116321   0.075503   1.541  0.12858    
log10(IST_PRC)       -0.710977   0.494219  -1.439  0.15538    
RNT_CPI              -0.005563   0.002643  -2.105  0.03945 *  
IST_CPI               0.015315   0.005132   2.984  0.00409 ** 
TR_PPI               -0.007335   0.002448  -2.996  0.00395 ** 
USD_RT                0.040256   0.051781   0.777  0.43991    
NEMP_RT              -0.012860   0.010775  -1.193  0.23731    
log10(IST_CNST_PT)    0.064872   0.049501   1.311  0.19493    
log10(IST_OCCP_PT_9)  0.105658   0.102583   1.030  0.30709    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.06506 on 61 degrees of freedom
Multiple R-squared:  0.8988,    Adjusted R-squared:  0.8823 
F-statistic: 54.21 on 10 and 61 DF,  p-value: < 2.2e-16
## estimates are the coefficient of the variables in a equation. y = ax + by + cz 

Remove from model USD_RT, NEMP_RT, CNST & OCCP Permits, RNT_CPI

model10_mn <- lm(log10(IST_MRTG_SL) ~ MG_RT + log10(IST_FGR_SL) + 
                    log10(IST_PRC) + 
                    IST_CPI + 
                    TR_PPI , 
                data = IST_RPPI_MODEL)
summary(model10_mn)

Call:
lm(formula = log10(IST_MRTG_SL) ~ MG_RT + log10(IST_FGR_SL) + 
    log10(IST_PRC) + IST_CPI + TR_PPI, data = IST_RPPI_MODEL)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.187080 -0.039010  0.002511  0.045031  0.221918 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        5.554099   1.022878   5.430  8.7e-07 ***
MG_RT             -0.040984   0.004293  -9.546  4.7e-14 ***
log10(IST_FGR_SL)  0.203193   0.062403   3.256  0.00178 ** 
log10(IST_PRC)    -0.591437   0.399044  -1.482  0.14306    
IST_CPI            0.005162   0.002764   1.868  0.06627 .  
TR_PPI            -0.004112   0.001765  -2.330  0.02288 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.06659 on 66 degrees of freedom
Multiple R-squared:  0.8854,    Adjusted R-squared:  0.8767 
F-statistic:   102 on 5 and 66 DF,  p-value: < 2.2e-16

Final step IST_PRC and IST_CPI are not in confidence p-value, remove from model.

model11_mn <- lm(log10(IST_MRTG_SL) ~ MG_RT + log10(IST_FGR_SL) +  
                    TR_PPI , 
                data = IST_RPPI_MODEL)
summary(model11_mn)

Call:
lm(formula = log10(IST_MRTG_SL) ~ MG_RT + log10(IST_FGR_SL) + 
    TR_PPI, data = IST_RPPI_MODEL)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.221901 -0.038148  0.006199  0.037142  0.214488 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)        4.0644591  0.0999960  40.646  < 2e-16 ***
MG_RT             -0.0447582  0.0037657 -11.886  < 2e-16 ***
log10(IST_FGR_SL)  0.1971191  0.0520759   3.785 0.000327 ***
TR_PPI            -0.0006944  0.0002850  -2.437 0.017437 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.0677 on 68 degrees of freedom
Multiple R-squared:  0.8779,    Adjusted R-squared:  0.8725 
F-statistic:   163 on 3 and 68 DF,  p-value: < 2.2e-16


Final outcome show us Property Sales with Mortgage is highly negative correlated with Mortgage Rates what It is easily expected. Turkey Producer Price Index also negative correlated with Mortgage Sales but Foreigner Sales strongly correlated with Foreigner Sales. When Foreigner Sales increase, Mortgage Sales also increasing.

For this study created and built different models. First of all in Model-1 include all variables which have logical correlation coefficients.

Housing Price Model

  • Created model with the most logical variables in Model-1

  • Eliminated one by one according to the P-Value.

  • Housing Price Model 

\[ R² = 0.91 \]


\[ log10(HousingPrice) = 0.07xlog10(FRGNRSL)+0.003xRentCPI-0.05xUSDRate+0.07xlog10(CNSTPRMT)+2.175 \]


Mortgage Sale Model

  1. Model 11 is explaining the Housing Sales By Using Loan, all big numbers like thousand reduced with log10. To many irrelevant p-values observed in model 8. Related Index numbers removed from model.

  2. P-values which is bigger than 0.05 eliminated one by one and the final model.

  3. Final model

\[R² = 0.83\]


\[ log10(Sales) = 0.197xlog10(FRGNRSL)-0.045xMGRT-0.0007xTRPPI+4.064 \]


##### 9.3. Residential Property Price Index Monthly Changes - Creating Different Models and See Residuals -  
#model1_cg <- lm(IST_PRC ~ MG_RT + IST_FGR_SL + IST_PRP_SL + IST_MRTG_SL + CNSTR_TRST + RNT_CPI + IST_CPI + TR_PPI + USD_RT + NEMP_RT + IST_CNST_PT +  IST_OCCP_PT_9 , data = train_cg)
#summary(model1_cg)
#model2_cg <- lm(IST_PRC ~ MG_RT + IST_FGR_SL + IST_PRP_SL + IST_MRTG_SL + CNSTR_TRST + RNT_CPI + IST_CPI + TR_PPI + USD_RT + NEMP_RT + IST_CNST_PT +  IST_OCCP_PT_9 , data = train_cg)
#summary(model2_cg)
#model3_cg <- lm(IST_PRC ~ IST_FGR_SL + IST_PRP_SL + IST_MRTG_SL + RNT_CPI + IST_CPI + TR_PPI + IST_CNST_PT +  IST_OCCP_PT_9 , data = train_cg)
#summary(model3_cg)
#model4_cg <- lm(IST_PRC ~ RNT_CPI + IST_FGR_SL , data = train_cg)
#summary(model4_cg)
#This model include the change rates of Housing Unit Prices and other variables. So try to explain Unit Prices with different undependent variables.

0.0.2.10 Residuals - Outliers

For all model errors below in the table according to AIC & BIC.

library(stats)
AIC(model1_mn, 
    model2_mn, 
    model3_mn, 
    model4_mn, 
    model5_mn, 
    model6_mn, 
    model7_mn, 
    model8_mn, 
    model9_mn, 
    model10_mn,
    model11_mn)
BIC(model1_mn,
    model2_mn,
    model3_mn,
    model4_mn,
    model5_mn,
    model6_mn,
    model7_mn,
    model8_mn,
    model9_mn,
    model10_mn,
    model11_mn)

Related with Model-7 Residuals, Outliers showed on the plot.

## model2
res1_mn <- residuals(model7_mn)
res1_mn <- as.data.frame(res1_mn)
ggplot(res1_mn, aes(res1_mn)) + 
        geom_histogram(fill = 'green', alpha = 0.5)

plot(model7_mn)

##model2
## res2 <- residuals(model2)
## 
## res2 <- as.data.frame(res2)
## 
## ggplot(res2, aes(res2)) + geom_histogram(fill = 'green', alpha = 0.5)
## 
## plot(model2)
IST_RPPI_MODEL$predicted.IST_PRC <- predict(model7_mn, IST_RPPI_MODEL)
pl1_mn <- IST_RPPI_MODEL %>%
    ggplot(aes(IST_PRC, predicted.IST_PRC)) +
    geom_point(alpha = 0.80) +
    stat_smooth(aes(colour = 'black')) +
    xlab('Actual Housing Unit Prices') +
    ylab('Predicted Housing Unit Prices') +
    theme_bw()
ggplotly(pl1_mn)
`geom_smooth()` using method = 'loess' and formula 'y ~ x'

0.0.2.11 Errors

Root Mean Square Error of Model-7:

error <- log10(IST_RPPI_MODEL$IST_PRC-IST_RPPI_MODEL$predicted.IST_PRC)
rmse <- sqrt(mean(error)^2)
data.frame(error)
data.frame(rmse)

Tried for each observations to estimate the real and predicted value in Model-7 In this case, using logarithm process for the errors because of the model include Housing Price with Log10. So this errors say us differences between Real Housing Price and The model which built to explain housing price.


0.0.3 Time Series

Autoregressive Integrated Moving Average

In statistics and econometric, and in particular in time series analysis, an auto regressive integrated moving average (ARIMA) model is a generalization of an auto regressive moving average (ARMA) model. Both of these models are fitted to time series data either to better understand the data or to predict future points in the series (forecasting). ARIMA models are applied in some cases where data show evidence of non-stationarity, where an initial differencing step (corresponding to the “integrated” part of the model) can be applied one or more times to eliminate the non-stationary.
The AR part of ARIMA indicates that the evolving variable of interest is regressed on its own lagged (i.e., prior) values. The MA part indicates that the regression error is actually a linear combination of error terms whose values occurred contemporaneously and at various times in the past. The I (for “integrated”) indicates that the data values have been replaced with the difference between their values and the previous values (and this difference process may have been performed more than once). The purpose of each of these features is to make the model fit the data as well as possible.
Non-seasonal ARIMA models are generally denoted ARIMA(p,d,q) where parameters p, d, and q are non-negative integers, p is the order (number of time lags) of the auto regressive model, d is the degree of difference (the number of times the data have had past values subtracted), and q is the order of the moving-average model. Seasonal ARIMA models are usually denoted ARIMA(p,d,q)(P,D,Q)m, where m refers to the number of periods in each season, and the uppercase P,D,Q refer to the auto regressive, difference, and moving average terms for the seasonal part of the ARIMA model.
When two out of the three terms are zeros, the model may be referred to based on the non-zero parameter, dropping “AR”, “I” or “MA” from the acronym describing the model. For example, ARIMA (1,0,0) is AR(1), ARIMA(0,1,0) is I(1), and ARIMA(0,0,1) is MA(1).
ARIMA models can be estimated following the Box-Jenkins approach.

This analysis help us to understand the housing price changes will be in 6 months

0.0.3.1 Set The Libraries

Setting the libraries which will using on analyze.

library(ggplot2)
library(forecast)
library(tseries)
library(astsa)
library(readr)

0.0.3.2 Data Import

The data include monthly changes of unit housing prices at Istanbul

library(readr)
IST_UNTPRC_FRCST <- read_csv("IST_UNTPRC_FRCST.csv", 
                             col_types = cols(DATE = col_date(format = "%d.%m.%Y")))
head(IST_UNTPRC_FRCST)

0.0.3.3 Show The Distribution of Housing Price Index 

Distribution of Monthly Housing Price Changes:

ggplot(IST_UNTPRC_FRCST, aes(DATE, IST_PRC_CG)) + 
    geom_line() + scale_x_date('Years')  + 
    ylab("Istanbul Housing Price Monthly Changes") +
            xlab("")

0.0.3.4 Clean The Outliers with Tsclean

Cleaning the trend of monthly changes to get linear, handle with extreme outliers.

count_ts = ts(IST_UNTPRC_FRCST[, c('IST_PRC_CG')])
IST_UNTPRC_FRCST$clean_cnt = tsclean(count_ts)
ggplot() +
  geom_line(data = IST_UNTPRC_FRCST, aes(x = DATE, y = clean_cnt)) + 
    ylab('Cleaned Istanbul Housing Price Monthly Changes')

0.0.3.5 Quarterly and Monthly Moving Averages

Divide into data some different periods to forecast more accuracy.

IST_UNTPRC_FRCST$cnt_ma1 = ma(IST_UNTPRC_FRCST$clean_cnt, order=1)
IST_UNTPRC_FRCST$cnt_ma2 = ma(IST_UNTPRC_FRCST$clean_cnt, order=2)
IST_UNTPRC_FRCST$cnt_ma3 = ma(IST_UNTPRC_FRCST$clean_cnt, order=3)
IST_UNTPRC_FRCST$cnt_ma6 = ma(IST_UNTPRC_FRCST$clean_cnt, order=6)
IST_UNTPRC_FRCST$cnt_ma12 = ma(IST_UNTPRC_FRCST$clean_cnt, order=12)
ggplot() +
  geom_line(data = IST_UNTPRC_FRCST, aes(x = DATE, 
                                         y = clean_cnt, 
                                         colour = "Istanbul Housing Monthly Changes Cleaned")) +
  geom_line(data = IST_UNTPRC_FRCST, aes(x = DATE, 
                                         y = cnt_ma1,   
                                         colour = "1 Monthly Moving Average"))  +
  geom_line(data = IST_UNTPRC_FRCST, aes(x = DATE, 
                                         y = cnt_ma2,   
                                         colour = "2 Monthly Moving Average"))  +
  geom_line(data = IST_UNTPRC_FRCST, aes(x = DATE, 
                                         y = cnt_ma3,   
                                         colour = "3 Monthly Moving Average"))  +
  geom_line(data = IST_UNTPRC_FRCST, aes(x = DATE, 
                                         y = cnt_ma6,   
                                         colour = "6 Monthly Moving Average"))  +
  geom_line(data = IST_UNTPRC_FRCST, aes(x = DATE, 
                                         y = cnt_ma12,  
                                         colour = "12 Monthly Moving Average")) +
  ylab('Istanbul RPPI Monthly Changes')

0.0.3.6 Decompose - Forecasting The Data

Decomposing data to get rid of seasonality. Chooses the frequency two. This means Auto Regressive Term and Moving Avarages according to two months.

count_ma = ts(na.omit(IST_UNTPRC_FRCST$cnt_ma2), 
              frequency=2)
decomp = stl(count_ma, 
             s.window = "periodic")
deseasonal_cnt <- seasadj(decomp)
plot(decomp)

  • Data : The trend isn’t in balance and very variable term.
  • Seasonality: Not in seasonality
  • Trend: Changes are going down for the last 5-6 periods.
  • Remainder: Show us the lag of data. In the 16th period.

0.0.3.7 Stationarity - ADF Test

adf.test(count_ma, 
         alternative = "stationary")

    Augmented Dickey-Fuller Test

data:  count_ma
Dickey-Fuller = -2.5629, Lag order = 4, p-value = 0.3432
alternative hypothesis: stationary

Now, testing model with ADF - Augmented Dickey Fuller Test, p-value bigger than .05

0.0.3.8 Autocorrelation and Choosing Model Order (ACF)

Auto correlation, also known as serial correlation, is the correlation of a signal with a delayed copy of itself as a function of delay. Informally, it is the similarity between observations as a function of the time lag between them. The analysis of auto correlation is a mathematical tool for finding repeating patterns, such as the presence of a periodic signal obscured by noise, or identifying the missing fundamental frequency in a signal implied by its harmonic frequencies. It is often used in signal processing for analyzing functions or series of values, such as time domain signals.

Different fields of study define autocorrelation differently, and not all of these definitions are equivalent. In some fields, the term is used interchangeably with autocovariance.

Unit root processes, trend stationary processes, auto regressive processes, and moving average processes are specific forms of processes with auto correlation.

##autocorrelation 
Acf(count_ma, main ="", plot = TRUE)

Pacf(count_ma, main ="",  plot = TRUE)

#Acf(count_ma, main ="", plot = FALSE)
#Pacf(count_ma, main ="",  plot = FALSE)

There are no stationary in the model, Lags are keeping decrease untill 18th periods.

0.0.3.9 Tune The Model

count_d1 = diff(deseasonal_cnt, differences = 2)
plot(count_d1)

adf.test(count_d1, alternative = "stationary" )
p-value smaller than printed p-value

    Augmented Dickey-Fuller Test

data:  count_d1
Dickey-Fuller = -6.2587, Lag order = 4, p-value = 0.01
alternative hypothesis: stationary

If the p value was bigger than 0.05, Differences should be use again. The model’s p-value ~ .01
This process using errors to forecast previous periods.

## count_d2 = diff(count_d1, differences = 1)
## plot(count_d2)
## adf.test(count_d2, alternative = "stationary" )
Acf(count_d1, 
    main = "ACF for Differenced Series")

Pacf(count_d1, 
     main = "PACF for Differenced Series")

#Acf(count_d1, 
#    main = "ACF for Differenced Series", plot = FALSE)
#Pacf(count_d1, 
#     main = "PACF for Differenced Series", plot = FALSE)

Lags can be observed in 3rd months because of the model array order is 3. To justify the model lag max should be 3. At 9th month’s lag isn’t in trust line. Fitting and Autoarima should be try.

0.0.3.10 Fitting an ARIMA Model

auto.arima(deseasonal_cnt, seasonal = FALSE)
Series: deseasonal_cnt 
ARIMA(2,1,2) 

Coefficients:
         ar1      ar2     ma1      ma2
      0.7675  -0.5081  0.0884  -0.7289
s.e.  0.0983   0.0912  0.0804   0.0771

sigma^2 estimated as 0.1038:  log likelihood=-29.71
AIC=69.42   AICc=70.03   BIC=82.69

Auto arima say to model use Auto Regressive Term and Moving Average Two, Difference period is one.

0.0.3.11 Evaluate and Iterate

fit1 <- auto.arima(deseasonal_cnt, 
                   seasonal = FALSE)
tsdisplay(residuals(fit1), lag.max = 18, 
          main = "(2,1,2) Model Residuals")

#fit2 = arima(deseasonal_cnt, order = c(1,1,1))
#fit2
#tsdisplay(residuals(fit2), lag.max = 12, main ="Seasonal Model Residuals")
fcast <- forecast(fit1, h = 6)
plot(fcast)

hold <- window(ts(deseasonal_cnt), start = 60)
fit_no_holdout = arima(ts(deseasonal_cnt[-c(78:89)]), 
                       order = c(2,1,2))
fcast_no_holdout <- forecast(fit_no_holdout, h = 6)
plot(fcast_no_holdout, main = "")
lines(ts(deseasonal_cnt))

fit_w_seasonality = auto.arima(deseasonal_cnt, seasonal=TRUE)
fit_w_seasonality
Series: deseasonal_cnt 
ARIMA(1,1,1)(1,0,2)[2] 

Coefficients:
         ar1     ma1    sar1     sma1    sma2
      0.2992  0.7402  0.9749  -1.8786  0.9037
s.e.  0.1703  0.1726  0.0448   0.0838  0.0823

sigma^2 estimated as 0.09516:  log likelihood=-26.99
AIC=65.98   AICc=66.84   BIC=81.9

0.0.3.12 Forecast The Istanbul Housing Price Changes

Actual Value of The Price Index

DATE IST RPPI CHANGE UNIT PRICES UNIT PRICE CHANGE
1.01.2019 100.15 -1.84 4900.15 -3.66
2.02.2019 99.63 -0.52 4702.03 -4.04
3.03.2019 99.34 -0.29 4657.59 -0.95
seas_fcast <- forecast(fit_w_seasonality, h=12)
plot(seas_fcast)

summary(seas_fcast)

Forecast method: ARIMA(1,1,1)(1,0,2)[2]

Model Information:
Series: deseasonal_cnt 
ARIMA(1,1,1)(1,0,2)[2] 

Coefficients:
         ar1     ma1    sar1     sma1    sma2
      0.2992  0.7402  0.9749  -1.8786  0.9037
s.e.  0.1703  0.1726  0.0448   0.0838  0.0823

sigma^2 estimated as 0.09516:  log likelihood=-26.99
AIC=65.98   AICc=66.84   BIC=81.9

Error measures:
                      ME      RMSE       MAE       MPE     MAPE      MASE
Training set -0.02015907 0.2996248 0.2265602 -2.891127 35.16316 0.3256143
                    ACF1
Training set 0.009417765

Forecasts:




0.0.4 The Result

The result of the study “Housing Prices in Istanbul” are more impose by Consumer and Producer Index related with Rent, USD Currency Rate, Construction Permits and Foreigner Sales. Some Index and Rates directly affecting Prices&Sales. The final model below with the equation:


\[ log10(HousingPrice) = 0.07xlog10(FRGNRSL)+0.003xRentCPI-0.05xUSDRate+0.07xlog10(CNSTPRMT)+2.175 \]


\[ log10(Sales) = 0.197xlog10(FRGNRSL)-0.045xMGRT-0.0007xTRPPI+4.064 \]


Regression analysis proved that the other independent variables may affecting less than consumer and procuder index. Time Series Analysis also proved that Housing Market in Istanbul will be negative growth for 6 months as well will be decreasing The Housing Prices for 6 months.




0.0.5 References

  1. Linear Regression, Selva Prabhakaran
  2. Linear Regression with Boston Housing Data set, Sukesh Kumar Pabba
  3. Introduction to Forecasting with ARIMA in R, Ruslana Dalinina
  4. https://en.wikipedia.org/wiki/Autoregressive_integrated_moving_average
  5. https://en.wikipedia.org/wiki/Autocorrelation\
  6. Overview Of The Real Estate And Housing Industry , May 2018
  7. Kaya, Aslı , “Determining of The Factors Affects Housing Price in Turkey with Hedonic Price Model”, CBRT Expertise Qualification Thesis Unpublished,Ankara , 2012




LS0tDQp0aXRsZTogIlJlYWwgRXN0YXRlIE1vZGVsbGluZyAmIEZvcmVjYXN0aW5nIg0KYXV0aG9yOiAiQWxwYXJzbGFuIFlBUklLVEFTIg0KZGF0ZTogIjI0LjA1LjIwMTkiDQpvdXRwdXQ6IA0KICB3b3JkX2RvY3VtZW50OiANCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgZmlnX2hlaWdodDogNS41DQogICAgZmlnX3dpZHRoOiA5DQogICAgaGlnaGxpZ2h0OiBlc3ByZXNzbw0KICAgIGtlZXBfbWQ6IHllcw0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogIGh0bWxfbm90ZWJvb2s6IA0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBmaWdfaGVpZ2h0OiA1LjUNCiAgICBmaWdfd2lkdGg6IDgNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBmaWdfaGVpZ2h0OiA1LjUNCiAgICBmaWdfd2lkdGg6IDkNCiAgICBoaWdobGlnaHQ6IGVzcHJlc3NvDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0aGVtZTogcGFwZXINCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KLS0tDQoNCg0KPGNlbnRlcj4hW10oaXR1LnBuZyk8L2NlbnRlcj5cDQoNCg0KXA0KXA0KXA0KXA0KXA0KDQoNCjxjZW50ZXI+KipFWFBMQUlOSU5HIElTVEFOQlVMIEhPVVNJTkcgUFJJQ0UgV0lUSCBFQ09OT01JQyBJTkRJQ0FUT1JTICYgRk9SRUNBU1RJTkcgVU5JVCBQUklDRVMgQ0hBTkdFKio8L2NlbnRlcj5cDQoNClwNClwNClwNCg0KDQoNCjxjZW50ZXI+QWxwYXJzbGFuIFlBUklLVEFTPC9jZW50ZXI+XA0KPGNlbnRlcj4qNTE2MTcxMDAzKjwvY2VudGVyPlwNCg0KDQpcDQpcDQoNCg0KIyMjIEludHJvZHVjdGlvblwNCg0KDQojIyMjIFByb2JsZW0gUXVlc3Rpb25cDQoNCg0KMS4gSG93IFRoZSBFY29ub21pYyBJbmRpY2F0b3JzIEFmZmVjdCBvbiBIb3VzaW5nIFVuaXQgUHJpY2UgYXQgSXN0YW5idWw/XA0KDQoyLiBXaGljaCBpbmRpY2F0b3JzIG1vcmUgZG9taW5hbnQgb24gdGhlIHByaWNlcz9cDQoNCjMuIFdoYXQgaXMgdGhlIGVxdWF0aW9uIGZvciBJc3RhbmJ1bCBVbml0IEhvdXNpbmcgUHJpY2U/XA0KDQo0LiBXaGF0IHdpbGwgYmUgdGhlIGhvdXNpbmcgcHJpY2UgZm9yIDYgbW9udGhzP1wNCg0KDQojIyMjIExpdGVyYXR1cmUgUmV2aWV3XA0KDQoNCiogVGhlIGNvbnN0cnVjdGlvbiBpbmR1c3RyeSBhbmQgb3RoZXIgcmVsYXRlZCBzdWIgaW5kdXN0cmllcyBhcmUgdGhlIG1vc3QgY3J1Y2lhbCBhc3BlY3RzIG9mIHRoZSBlY29ub215IFRoZQ0KVHVya2lzaCBob3VzaW5nIGluZHVzdHJ5IGhhcyBhY2hpZXZlZCBmYXN0IGdyb3d0aCBpbiB0aGUgcGFzdCBmaWZ0ZWVuIHllYXJzIFRoZSBtYWNyb2Vjb25vbWljIGltcG9ydGFuY2Ugb2YgdGhlDQpjb25zdHJ1Y3Rpb24gaW5kdXN0cnkgYXJpc2VzIGZyb20gaXRzIG11bHRpcGxpZXIgZWZmZWN0IEl0IHNldHMgMjUwIHN1YiBpbmR1c3RyaWVzIGluIG1vdGlvbiB3aXRoIGltcGFjdHMgb24gYm90aA0KZ3Jvd3RoIGFuZCBlbXBsb3ltZW50LlwNCg0KDQoqIEhvdXNpbmcgYW5kIHJlbGF0ZWQgaW50ZXJlc3RzIG1ha2UgdXAgYSBzaWduaWZpY2FudCBwb3J0aW9uIG9mIHRoZSBjb25zdHJ1Y3Rpb24gaW5kdXN0cnkgaW4gb3VyIGNvdW50cnkuIFRoZSBpbmR1c3RyeeKAmXMgZ3Jvd3RoIHJhdGUgaXMgaW5mbHVlbmNlZCBieSBib29tcy9zdGFnbmF0aW9uIG9ic2VydmVkIGluIGhvdXNpbmcgZGVtYW5kIGFuZCBzYWxlcy4gDQpUaGUgaW5kdXN0cnnigJlzIHNlbnNpdGl2aXR5IHRvIHRoZSB0b3RhbCBuYXRpb25hbCBncm93dGggaXMgYWxzbyBoaWdoLlwNCg0KDQoNCiogQXMgd2VsbCB0aGUgcHJpY2Ugb2YgYSBob21lIGluIHRoZSBob3VzaW5nIHNlY3RvciBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBiYWxhbmNlIG9mIGhvdXNpbmcgc3VwcGx5IGFuZCBkZW1hbmQgSW4gdGhlIHNob3J0IHRlcm0sIHRoZSBzdXBwbHkgb2YgaG91c2luZyBpcyBmb3IgdGhlIG1vc3QgcGFydCBmaXhlZCwgbWVhbmluZyB0aGF0IHRoZSBtYWluIHZhcmlhYmxlIGluIGRldGVybWluaW5nIGhvdXNpbmcgcHJpY2VzIGlzIHRoZSByaXNlIG9yIGRlY2xpbmUgaW4gZGVtYW5kIENvbnNlcXVlbnRseSwgaW4gdGhlIHNob3J0IHRlcm0sIHJpc2luZyBkZW1hbmQgZm9yIGhvdXNpbmcgY2F1c2VzIHByaWNlcyB0byBpbmNyZWFzZSBhbmQgZGVjbGluaW5nIGRlbWFuZCBjYXVzZXMgdGhlbSB0byBmYWxsLlwgDQoNCg0KKioqDQoNCg0KXA0KDQoNCg0KDQpJbiB0aGlzIHN0dWR5IFNlY3Rpb24gLSAxIGluY2x1ZGVzICJUaGUgUmVncmVzc2lvbiBBbmFseXNpcyIgdG8gZXhwbGFpbiB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIHdoaWNoIGlzICoqVW5pdCBIb3VzaW5nIFByaWNlIGluIElzdGFuYnVsKiogd2l0aCBpbmRlcGVuZGVudCB2YXJpYWJsZXMgYmVsb3cgaW4gdGhlIHRhYmxlIGFuZCB0cmllZCB0byBmaW5kICoqdGhlIGhpZ2hlc3QgYW5kIG1vc3QgZWZmZWN0aXZlIG1vZGVsKiogdGhhdCBleHBsYWluaW5nIHVuaXQgaG91c2luZyBwcmljZS4NCkluIFNlY3Rpb24gQiwgIlRoZSBBUklNQSBBbmFseXNpcyIgdXNlZCBmb3IgZm9yZWNhc3RpbmcgdGhlICJIb3VzaW5nIFByaWNlIENoYW5nZXMgSW4gSXN0YW5idWwiIGZvciBzaXggbW9udGhzLiBUaGUgc3VtbWFyeSBvZiBzdHVkeSBhcyBpbiB0aGUgYmVsb3cgZm9sbG93aW5nIGNoYXJ0LlwNCg0KDQogDQogDQoNCioqU2VjdGlvbiAxIC0gQ3Jvc3MgU2VjdGlvbioqICAgICAgICAgICAgfCAqKlNlY3Rpb24gMiAtIFRpbWUgU2VyaWVzKioNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gICAgfCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KUmVncmVzc2lvbiBBbmFseXNpcyAgICAgICAgICAgICAgICAgICAgICB8IEF1dG8gUmVncmVzc2l2ZSBJbnRlZ3JhdGVkIE1vdmluZyBBdmVyYWdlIEFuYWx5c2lzDQpFeHBsYWluaW5nIElzdGFuYnVsIEhvdXNpbmcgVW5pdCBQcmljZSAgIHwgRm9yZWNhc3RpbmcgSXN0YW5idWwgSG91c2luZyBQcmljZSdzIENoYW5nZSBOZXh0IE1vbnRoDQoNCioqKg0KIA0KDQpTb21lIHZhcmlhYmxlcyBhbmQgZGVzY3JpcHRpb24gaW4gdGhlIGJlbG93IGNoYXJ0LlwNCiANCg0KDQoNCioqVkFSSUFCTEVTKiogICAgfCAqKkRFU0NSSVBUSU9OKioNCi0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoqKkRBVEUqKiAgICAgICAgIHwgTW9udGhseSBEYXRlIGZyb20gMjAxMyB0byAyMDE5DQoqKklTVF9SUFBJKiogICAgIHwgSXN0YW5idWwgUmVzaWRlbnRpYWwgUHJvcGVydHkgUHJpY2UgSW5kZXgNCioqSVNUX1BSQyoqICAgICAgfCBJc3RhbmJ1bCBIb3VzaW5nIFVuaXQgUHJpY2UgVEwvbcKyDQoqKklTVF9DTlNUX1BSTVQqKnwgQ29uc3RydWN0aW9uIFBlcm1pdHMNCioqSVNUX09DQ1BfUFJNVCoqfCBPY2N1cGF0aW9uYWwgUGVybWl0cw0KKipNR19SVCoqICAgICAgICB8IE1vcnRnYWdlIENyZWRpdCBSYXRlcw0KKipJU1RfRkdSX1NMKiogICB8IElzdGFuYnVsIEhvdXNpbmcgU2FsZXMgdG8gT25seSBGb3JlaWduZXJzIA0KKipJU1RfUFJQX1NMKiogICB8IElzdGFuYnVsIFRvdGFsIEhvdXNpbmcgU2FsZXMNCioqSVNUX01SVEdfU0wqKiAgfCBJc3RhbmJ1bCBIb3VzaW5nIFNhbGVzIGJ5IFVzaW5nIE1vcnRnYWdlIExvYW4NCioqQ05TVFJfVFJTVCoqICAgfCBDb25zdHJ1Y3Rpb24gVHJ1c3QgSW5kZXgNCioqSVNUX0NQSSoqICAgICAgfCBJc3RhbmJ1bCBDb25zdW1lciBQcmljZSBJbmRleA0KKipUUl9QUEkqKiAgICAgICB8IFR1cmtleSBQcm9kdWNlciBQcmljZSBJbmRleA0KKipVU0RfUlQqKiAgICAgICB8IFVTRCBCdXlpbmcgRXhjaGFuZ2UgUmF0ZQ0KKipSTlRfQ1BJKiogICAgICB8IElTVCBSZW50IENvbnN1bWVyIFByaWNlIEluZGV4DQoqKk5FTVBfUlQqKiAgICAgIHwgVW5lbXBsb3ltZW50IFJhdGUNCg0KDQoNCiANCiAqKk5vdGVzIDogSVNUX0NOU1RfUFJNVCAtIElTVF9PQ0NQX1BSTVQgZm9yd2FyZCBzb21lIGRpZmZlcmVudCBwZXJpb2RzIDIsMyw0LDYsOSBldGMuKipcDQoNCg0KXA0KXA0KDQoNCioqKg0KDQpcDQoNCg0KRm9yIHRoZSByZWFzb24gd2h5IHVzaW5nIGJvdGggKlByaWNlIEluZGV4KiBhbmQgKlVuaXQgUHJpY2VzKiBtYWluIHB1cnBvc2Ugb2YgdGhlIHVzaW5nIGJvdGggUHJpY2UgSW5kZXggYW5kIFByaWNlcyBvbiB0aGUgZGF0YSBzZXQgaW4gb3JkZXIgdG8gc2VlIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIE1vbnRobHkgUHJvcGVydHkgUHJpY2UgSW5kZXggYW5kIFVuaXQgUHJpY2VzIGFuZCBjcm9zcyBjaGVjayBvdXIgb2JzZXJ2YXRpb25zLlwNCkl0IGNhbiBlYXNpbHkgZXhwZWN0IHRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBhcHJveGltYXRlbHkgfiA5OSVcDQpUaGUgbWFpbiB2YWx1ZSBvZiBIb3VzaW5nIFByaWNlcyBJbmRleCBhbmQgVW5pdCBQcmljZXMgd291bGQgYmUgdGhlIGV4cGVjdGluZyBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCB3aGljaCBpcyBhcHByb3hpbWF0ZWx5IDAuOTYgYnV0IHRoZSBtb250aGx5IHBlcmNlbnRhZ2UgY2hhbmdlcyBiZXR3ZWVuIHRoZW0gd291bGRuJ3QgYmUgdGhlIGJpZ2dlciB0aGFuIDgwJS5cDQoNClRoaXMgc3R1ZHkgYWxzbyBwcm92ZSB0aGlzIG9uIHRoZSBuZXh0IHBhcmFncmFwaHMuXA0KIA0KDQoNCg0KIyMjIENyb3NzIFNlY3Rpb25cDQogDQojIyMjIFNldHRpbmcgVGhlIExpYnJhcmllc1wNCg0KQmVmb3JlIHN0YXJ0IHRoZSBzdHVkeSwgdGhlIGxpYnJhcmllcyBzaG91bGQgYmUgaW1wb3J0IHRvIGdldCByaWQgb2YgdGhlIGVycm9ycyBhbmQgaGVscCB0byBhbmFseXplIGFsbCBpbiBvbmUgZm9yIHN0dWR5Lg0KDQpgYGB7ciBMaWJyYXJ5IH0NCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KG1sYmVuY2gpDQpsaWJyYXJ5KGNvcnJwbG90KQ0KbGlicmFyeShBbWVsaWEpDQpsaWJyYXJ5KGNhcmV0KQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGNhVG9vbHMpDQpsaWJyYXJ5KHJlc2hhcGUyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGZvcmVjYXN0KQ0KbGlicmFyeSh0c2VyaWVzKQ0KbGlicmFyeShhc3RzYSkNCmxpYnJhcnkocmVhZHIpDQpgYGANCg0KDQojIyMjIERhdGEgSW1wb3J0XA0KDQoNCg0KVGhpcyBwcm9qZWN0IGluY2x1ZGUgZGlmZmVyZW50IHN0dWRpZXMgdGhhdCBkaXZpZGUgbWFpbiB2YWx1ZXMgYW5kIHBlcmNlbnRhZ2UgY2hhbmdlIGFjY29yZGluZyB0byB0aGUgcHJldmlvdXMgbW9udGhzLlwNCg0KDQoqKklTVF9SUFBJX01PREVMKiogICAgICAgICAgICB8ICoqSVNUX1JQUElfTU9ERUxfQ0cqKg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpNYWluIFZhbHVlIG9mIEFsbCB2YXJpYWJsZXMgICB8IE1vbnRobHkgUGVyY2VudGFnZSBDaGFuZ2VzIFZhbHVlcyglKQ0KDQoNClwNCg0KDQpgYGB7ciBEYXRhIEltcCB9DQpsaWJyYXJ5KHJlYWRyKQ0KSVNUX1JQUElfTU9ERUwgPC0gcmVhZF9jc3YoIklTVF9SUFBJX01PREVMLmNzdiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gY29scyhEQVRFID0gY29sX2RhdGUoZm9ybWF0ID0gIiVkLiVtLiVZIikpKQ0KSVNUX1JQUElfTU9ERUxfQ0cgPC0gcmVhZF9jc3YoIklTVF9SUFBJX01PREVMX0NHLmNzdiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gY29scyhEQVRFID0gY29sX2RhdGUoZm9ybWF0ID0gIiVkLiVtLiVZIikpKQ0KI1ZpZXcoSVNUX1JQUElfTU9ERUwpDQojVmlldyhJU1RfUlBQSV9NT0RFTF9DRykNCmBgYA0KDQojIyMjIERhdGEgVHlwZSBPYnNlcnZhdGlvblwNCg0KDQpBbGwgdGhlIHZhcmlhYmxlcyBhY2NvcmRpbmcgdG8gZGF0YSB0eXBlIGlzICoiZGJsIiogdGhhdCBpcyByZWxhdGVkIHdpdGggbnVtZXJpYyB2YWx1ZXMgZXhjZXB0ICJEYXRlIi5cDQpUaGUgc3R1ZHkgaXMgbm90IGdvaW5nIHRvIGluY2x1ZGUgKipkYXRlcyoqIGluIGFueSBtb2RlbCBhdCBTZWN0aW9uLTEgb24gUmVncmVzc2lvbiBBbmFseXNpcy4gDQpTZWVpbmcgdGhlIGRhdGEgdHlwZXMgYW5kIGZpcnN0IDUgY29sdW1uIGlzIGFsc28gaW1wb3J0YW50IGZvciB0aGUgZGF0YSBzZXQgd2hhdCBpbXBvcnRlZCBjb3JyZWN0bHkuXA0KDQpgYGB7ciBEYXRhIFR5cGUgfQ0KaGVhZChJU1RfUlBQSV9NT0RFTCkNCiNzdHIoSVNUX1JQUElfTU9ERUwpIC0gdG8gc2VlIHRoZSBkYXRhIHR5cGUNCiNmb3IgdGhlIG90aGVyIGRhdGFzZXQgDQojc3RyKElTVF9SUFBJX01PREVMX0NHKQ0KYGBgDQoNCg0KDQoNCiMjIyMgVW5kZXJzdGFuZGluZyBEYXRhXCANCg0KSW4gb3JkZXIgdG8gdW5kZXJzdGFuZCBhbmQgZXhhbWluZSBkYXRhIGdlbmVyYWxseSB1c2UgZml2ZSBudW1iZXIgc3VtbWFyeS5cDQoqRml2ZSBOdW1iZXIgU3VtbWFyeSogc2hvd3MgKm1lZGlhbiosICptZWFuKiwgKm1pbi1tYXgqIGFuZCAqUTEgJiBRMyogdmFsdWVzLlwNClRoaXMgbWF5IGhlbHAgdXMgdG8gbWluaW5nIGFuZCBlbGltaW5hdGluZyBhbmQgdW5kZXJzdGFuZGluZyB0aGUgc3RydWN0dXJlIG9mIGRhdGEgYW5kIGNsYXNzaWZ5aW5nIHRoZSBvYnNlcnZhdGlvbnMuXA0KDQoqKkZvciBleGFtcGxlIDoqKlwNCg0KDQoNCiogSG91c2luZyBVbml0IFByaWNlcyBpbiBJc3RhbmJ1bCBoYXMgbWluaW11bSB2YWx1ZSB3aGljaCBpcyAyMDY0IDsgTWVhbiBWYWx1ZSBpcyAzNzA4IGFuZCBhbHNvIHRoZSBNZWRpYW4gVmFsdWUgaXMgMzkyMi4gUTMgaXMgNDU2MiBhbmQgTWF4LiB2YWx1ZSA1MTIzLiBJdCBjYW4gYmUgZWFzaWx5IHVuZGVyc3RhbmRpbmcgdGhpcyBkYXRhIGNsYXNzaWZpZWQgd2l0aCBhIGdvb2QgcmFuZ2UgYmVjYXVzZSB0aGVyZSBpcyBub3QgYW55IGV4dHJlbWUgb2JzZXJ2YXRpb24uXA0KDQoNCiogSXN0YW5idWwgVW5pdCBQcmljZSBDaGFuZ2VzICBtaW4udmFsdWUgLTEuMjY2LCBtYXgudmFsdWUgMy43NTYsIG1lYW4gMS4yODUsIG1lZGlhbiAxLjM2NlwNCg0KDQoqIFRvdGFsIElzdGFuYnVsIEhvdXNpbmcgU2FsZXMgbWluLnZhbHVlIDExOTAzLCBtYXgudmFsdWUgMjcxNTYsIG1lYW4gdmFsdWUgMTk1MTIsIG1lZGlhbiB2YWx1ZSAxOTMwNS4gM3JkIFF1YXJ0aWxlIHZhbHVlIGlzIDIxMjEzIFRoaXMgdmFsdWUgc2hvd3MgdXMgdGhlcmUgaXMgbm90IGFueSBleHRyZW1lIGNpcmN1bXN0YW5jZXMuXA0KDQoNCiogV2hlbiBpdCBjb21lcyB0byBtb3J0Z2FnZSByYXRlcyxcDQoNCg0KDQpNaW4ufDFzdCBRLnxNZWRpYW58TWVhbnwzcmQgUS58TWF4LiANCi0tLS18LS0tLS0tLXwtLS0tLS18LS0tLXwtLS0tLS0tfC0tLS0NCjguMzB8MTEuMDAgIHwxMi4yMCB8MTMuMTF8MTMuOTN8MjguOTkNCg0KDQoNClwNCg0KDQoNClRoZSBzaXR1YXRpb24gYWJvdXQgdGhlIG91dGxpZXJzIHdpbGwgYmUgc2NydXRpbml6ZWQgbmV4dCBwYXJhZ3JhcGhzLlwNCg0KDQoNCjEuIFVuaXQgSG91c2luZyBQcmljZVwNCmBgYHtyfQ0Kc3VtbWFyeShJU1RfUlBQSV9NT0RFTCRJU1RfUFJDKQ0KYGBgDQoNCjIuIFJlc2lkZW50aWFsIEhvdXNpbmcgUHJpY2UgSW5kZXhcDQpgYGB7cn0NCnN1bW1hcnkoSVNUX1JQUElfTU9ERUwkSVNUX1JQUEkpDQpgYGANCg0KMy4gUHJvcGVydHkgU2FsZXNcDQpgYGB7cn0NCnN1bW1hcnkoSVNUX1JQUElfTU9ERUwkSVNUX1BSUF9TTCkNCmBgYA0KDQo0LiBGb3JlaWduZXIgU2FsZXNcDQpgYGB7cn0NCnN1bW1hcnkoSVNUX1JQUElfTU9ERUwkSVNUX0ZHUl9TTCkNCmBgYA0KDQo1LiBTYWxlcyBieSBNb3J0Z2FnZVwNCmBgYHtyfQ0Kc3VtbWFyeShJU1RfUlBQSV9NT0RFTCRJU1RfTVJUR19TTCkNCmBgYA0KDQo2LiBPY2N1cGF0aW9uYWwgUGVybWl0cyBmb3J3YXJkIDkgbW9udGhzXA0KYGBge3J9DQpzdW1tYXJ5KElTVF9SUFBJX01PREVMJElTVF9PQ0NQX1BUXzkpDQpgYGANCg0KNy4gQ29uc3VtZXIgUHJpY2UgSW5kZXhcDQpgYGB7cn0NCnN1bW1hcnkoSVNUX1JQUElfTU9ERUwkSVNUX0NQSSkNCmBgYA0KDQo4LiBNb3J0Z2FnZSBSYXRlc1wNCmBgYHtyfQ0Kc3VtbWFyeShJU1RfUlBQSV9NT0RFTCRNR19SVCkNCmBgYA0KDQo5LiBDb25zdHJ1Y3Rpb24gUGVybWl0c1wNCmBgYHtyfQ0Kc3VtbWFyeShJU1RfUlBQSV9NT0RFTCRJU1RfQ05TVF9QVCkNCmBgYA0KMTAuIFJlbnQgQ29uc3VtZXIgUHJpY2UgSW5kZXhcDQpgYGB7cn0NCnN1bW1hcnkoSVNUX1JQUElfTU9ERUwkUk5UX0NQSSkNCmBgYA0KMTEuIFR1cmtleSBQcm9kdWNlciBQcmljZSBJbmRleFwNCmBgYHtyfQ0Kc3VtbWFyeShJU1RfUlBQSV9NT0RFTCRUUl9QUEkpDQpgYGANCjEyLiBVU0QgQ3VycmVuY3kgUmF0ZXNcDQpgYGB7cn0NCnN1bW1hcnkoSVNUX1JQUElfTU9ERUwkVVNEX1JUKQ0KYGBgDQoNCg0KYGBge3IgRml2ZS1OdW1iZXIgU3VtbWFyeX0NCiNzdW1tYXJ5KElTVF9SUFBJX01PREVMKQ0KYGBgDQoNClwNCg0KDQpgYGB7ciBDaGFuZ2VzIFN1bW1hcnl9DQojc3VtbWFyeShJU1RfUlBQSV9NT0RFTF9DRykNCiNzdW1tYXJ5KElTVF9SUFBJX01PREVMX0NHJElTVF9SUFBJKQ0KI3N1bW1hcnkoSVNUX1JQUElfTU9ERUxfQ0ckSVNUX0ZHUl9TTCkNCiNzdW1tYXJ5KElTVF9SUFBJX01PREVMX0NHJElTVF9NUlRHX1NMKQ0KI3N1bW1hcnkoSVNUX1JQUElfTU9ERUxfQ0ckSVNUX09DQ1BfUFRfOSkNCiNzdW1tYXJ5KElTVF9SUFBJX01PREVMX0NHJElTVF9DUEkpDQojc3VtbWFyeShJU1RfUlBQSV9NT0RFTF9DRyRNR19SVCkNCmBgYA0KDQpcDQoNCg0KVGhlIHZhbHVlcyB3aXRoIGJveCBwbG90IEluIGFkZGl0aW9uIHRvIG51bWVyaWMgdGFibGUsIEhvdXNpbmcgU2FsZXMgYWxzbyBiZSBzaG93ZWQgd2l0aCBib3ggcGxvdC5cDQoNCmBgYHtyIEJveFBsb3QgfQ0KYm94cGxvdChJU1RfUlBQSV9NT0RFTCRJU1RfUFJDLCBtYWluID0gIkhvdXNpbmcgUHJpY2VzIiwNCiAgICAgICAgc3ViPXBhc3RlKCJPdXRsaWVyIHJvd3M6ICAiLCBib3hwbG90LnN0YXRzKElTVF9SUFBJX01PREVMJElTVF9QUkMpJG91dCkpDQpib3hwbG90KElTVF9SUFBJX01PREVMJElTVF9NUlRHX1NMLCBtYWluID0gIkhvdXNpbmcgU2FsZXMgQnkgVXNpbmcgTG9hbiIsIA0KICAgICAgICBib3JkZXIgPSBwYXIoImZnIiksIA0KICAgICAgICBzdWI9cGFzdGUoIk91dGxpZXIgUm93czogICIsIGJveHBsb3Quc3RhdHMoSVNUX1JQUElfTU9ERUwkSVNUX01SVEdfU0wpJG91dCkpDQpib3hwbG90KElTVF9SUFBJX01PREVMJE1HX1JULCBtYWluID0gIk1vcnRnYWdlIFJhdGVzIiwNCiAgICAgICAgc3ViPXBhc3RlKCJPdXRsaWVyIFJvd3M6ICAiLCBib3hwbG90LnN0YXRzKElTVF9SUFBJX01PREVMJE1HX1JUKSRvdXQpKQ0KYm94cGxvdChJU1RfUlBQSV9NT0RFTCRJU1RfUlBQSSwgbWFpbiA9ICJQcm9wZXJ0eSBQcmljZSBJbmRleCIsDQogICAgICAgIHN1Yj1wYXN0ZSgiT3V0bGllciBSb3dzOiAgIiwgYm94cGxvdC5zdGF0cyhJU1RfUlBQSV9NT0RFTCRJU1RfUlBQSSkkb3V0KSkNCmJveHBsb3QoSVNUX1JQUElfTU9ERUwkSVNUX0ZHUl9TTCwgbWFpbiA9ICJGb3JlaWduZXIgU2FsZXMiLA0KICAgICAgICBzdWI9cGFzdGUoIk91dGxpZXIgUm93czogICIsIGJveHBsb3Quc3RhdHMoSVNUX1JQUElfTU9ERUwkSVNUX0ZHUl9TTCkkb3V0KSkNCmJveHBsb3QoSVNUX1JQUElfTU9ERUwkSVNUX09DQ1BfUFRfOSwgbWFpbiA9ICJPY2N1cGF0aW9uYWwgUGVybWl0cyBmb3J3YXJkIDkgbW9udGhzIiwNCiAgICAgICAgc3ViPXBhc3RlKCJPdXRsaWVyIFJvd3M6ICAiLCBib3hwbG90LnN0YXRzKElTVF9SUFBJX01PREVMJElTVF9PQ0NQX1BUXzkpJG91dCkpDQpib3hwbG90KElTVF9SUFBJX01PREVMJFVTRF9SVCwgbWFpbiA9ICJVU0QgRXhjaGFuZ2UgUmF0ZSIsDQogICAgICAgIHN1Yj1wYXN0ZSgiT3V0bGllciBSb3dzOiAgIiwgYm94cGxvdC5zdGF0cyhJU1RfUlBQSV9NT0RFTCRVU0RfUlQpJG91dCkpDQpib3hwbG90KElTVF9SUFBJX01PREVMJFJOVF9DUEksIG1haW4gPSAiUmVudCBDb25zdW1lciBQcmljZSBJbmRleCIsDQogICAgICAgIHN1Yj1wYXN0ZSgiT3V0bGllciBSb3dzOiAgIiwgYm94cGxvdC5zdGF0cyhJU1RfUlBQSV9NT0RFTCRSTlRfQ1BJKSRvdXQpKQ0KYGBgDQoNCmBgYHtyIE91dGxpZXJzfQ0KTUdfUlRfT1VUIDwtIGJveHBsb3Quc3RhdHMoSVNUX1JQUElfTU9ERUwkTUdfUlQpJG91dA0KTVJUR19TTF9PVVQgPC0gYm94cGxvdC5zdGF0cyhJU1RfUlBQSV9NT0RFTCRJU1RfTVJUR19TTCkkb3V0DQpkYXRhLmZyYW1lKE1HX1JUX09VVCwgTVJUR19TTF9PVVQpDQoNCklTVF9GR1JfU0xfT1VUIDwtIGJveHBsb3Quc3RhdHMoSVNUX1JQUElfTU9ERUwkSVNUX0ZHUl9TTCkkb3V0DQpJU1RfT0NDUF9QVF85X09VVCA8LSBib3hwbG90LnN0YXRzKElTVF9SUFBJX01PREVMJElTVF9PQ0NQX1BUXzkpJG91dA0KVVNEX1JUX09VVCA8LSBib3hwbG90LnN0YXRzKElTVF9SUFBJX01PREVMJFVTRF9SVCkkb3V0DQoNCmRhdGEuZnJhbWUoSVNUX0ZHUl9TTF9PVVQsIElTVF9PQ0NQX1BUXzlfT1VULCBVU0RfUlRfT1VUKQ0KDQpgYGANClwNCg0KDQoNCg0KKipNb3J0Z2FnZSBSYXRlcyBhbmQgTW9ydGdhZ2UgU2FsZXMgaGF2ZSA1IG91dGxpZXJzLCBGb3JlaWduZXIgU2FsZXMgNiwgIE9jY3VwYXRpb25hbCBwZXJtaXRzIDEgYW5kIDIgb3V0bGllcnMgaW4gVXNkIEV4Y2hhbmdlIFJhdGVzLioqXA0KDQoNClRoZSBvdXRsaWVycyBkaXN0cmFjdGluZyBtb2RlbCBjb25maWRlbmNlLCBvdGxpZXJzIHNob3VsZCByZW1vdmUgZnJvbSBkYXRhc2V0LiBJbiB0aGUgc3R1ZHkgb3V0bGllcnMgdXNlZCBiZWNhdXNlIG9mIHRoZSBzaXplLlwNCg0KDQpBbiBBbHRlcm5hdGl2ZSBzb2x1dGlvbiBtYXkgb2ZmZXIgcmVtb3ZlIHRoZSBvdXRsaWVycyBhbmQgKipmaWxsIHdpdGggbWVkaWFuIHZhbHVlKiogb2YgY29sdW1uLlwNCg0KDQoNCldoZW4gSXQgY29tZXMgdG8gKmRlcGVuZGVudCAtIGluZGVwZW5kZW50IHZhcmlhYmxlcyosIEl0IGNhbiBiZSBlYXNpbHkgc2hvd2luZyBkaXN0cmlidXRpb24gaW4gc2NhdHRlciBwbG90LlwNCg0KDQoNCioqRm9yIGV4YW1wbGUgOioqXA0KDQoNClNvbWUgZGlzdHJ1Yml0b25zIGFib3V0IEhvdXNpbmcgUHJpY2UgYW5kIG90aGVyIHZhcmlhYmxlcyBzaG93aW5nIHdpdGggdGhlIHNjYXR0ZXIgcGxvdC5cDQoNCg0KDQpgYGB7ciBTY2F0dGVyUGxvdCB9DQpzY2F0dGVyLnNtb290aCh4ID0gSVNUX1JQUElfTU9ERUwkTUdfUlQsIA0KICAgICAgICAgICAgICAgeSA9IElTVF9SUFBJX01PREVMJElTVF9QUkMsIA0KICAgICAgICAgICAgICAgbWFpbiA9ICJIb3VzaW5nIFByaWNlIH4gTW9ydGdhZ2UgUmF0ZXMiKQ0Kc2NhdHRlci5zbW9vdGgoeCA9IElTVF9SUFBJX01PREVMJElTVF9QUlBfU0wsIA0KICAgICAgICAgICAgICAgeSA9IElTVF9SUFBJX01PREVMJElTVF9QUkMsIA0KICAgICAgICAgICAgICAgbWFpbiA9ICJIb3VzaW5nIFByaWNlIH4gSG91c2luZyBTYWxlcyIpDQpzY2F0dGVyLnNtb290aCh4ID0gSVNUX1JQUElfTU9ERUwkUk5UX0NQSSwgDQogICAgICAgICAgICAgICB5ID0gSVNUX1JQUElfTU9ERUwkSVNUX1BSQywgDQogICAgICAgICAgICAgICBtYWluID0gIkhvdXNpbmcgUHJpY2UgfiBSZW50IFByaWNlIEluZGV4IikNCmBgYA0KDQoqIFRoaXMgcGxvdCBhbHNvIHNvcnQgb3V0IHRvIGNvcnJlbGF0aW9uLlwNCiogVGhlIHJlbGF0aW9uIGJldHdlZW4gcHJpY2UgJiBtb3J0Z2FnZSByYXRlcyBhbHNvIHBvc2l0aXZlIGNvcnJlbGF0aW9uIGJ1dCB0YWtpbmcgaW50byBjb25zaWRlcmF0aW9uIHRoYXQgc3VwcGx5IGFuZCBkZW1hbmQgZXF1aWxpYnJpdW0sIGV4cGVjdGluZyB3aGVuIG1vcnRnYWdlIHJhdGVzIGRvd24gcHJpY2VzIHdvdWxkIGJlIGhpZ2hlciBiZWNhdXNlIG9mIHRoZSBkZW1hbmQgd291bGQgaW5jcmVhc2luZy5cDQoqIFdoZW4gaXQgY29tZXMgdG8gVHVya2V5IGNvbnNpZGVyaW5nIHRoYXQgdGhlcmUgaXMgYW4gaW1iYWxhbmNlIHNpdHVhdGlvbi4gUGVvcGxlIGFsd2F5cyB3YW50aW5nIHRvIGdldCBhIGhvdXNpbmcgbmVpdGhlciBtb3J0Z2FnZSByYXRlcyBpbmNyZWFzZSBub3IgbW9ydGdhZ2UgcmF0ZXMgZGVjcmVhc2UuXA0KKiBUaGUgc3R1ZHkgZW1waGFzaXMgdGhpcyBzaXR1YXRpb24gb24gbmV4dCBwYXJhZ3JhcGhzIGF0IHRoZSBDb3JyZWxhdGlvbi5cDQoNCg0KSW4gb3JkZXIgdG8gc2VlIHRoZSBtaXNzaW5nIG9ic2VydmF0aW9ucywgZWFzaWx5IGdldCB0aGlzIGNvZGUgYnkgdXNpbmcgKkFtZWxpYSBQYWNrYWdlKi4gSW4gdGhpcyBzdHVkeSwgYW55IG1pc3NpbmcgdmFsdWUgdGhlIG1vZGVsIGluY2x1ZGluZy4gXA0KDQoNCg0KIyMjIyBTZWUgVGhlIE1pc3NpbmcgVmFsdWVzXCANCg0KYGBge3IgTWlzc2luZyBWYWx1ZXMgfQ0KIyBpbiBvcmRlciB0byBzZWUgdGhlIHN1bSBvZiBtaXNzaW5nIHZhbHVlcw0KIyBjb2xTdW1zKGlzLm5hKElTVF9SUFBJX01PREVMKSkNCiMgZm9yIHNob3cgdGhlIHBsb3Qgb2YgdGhlIG1pc3NpbmcgdmFsdWVzDQptaXNzbWFwKElTVF9SUFBJX01PREVMLCBjb2w9YygncmVkJywgJ2dyZWVuJyksIA0KICAgICAgICB5LmF0PTEsIHkubGFiZWxzID0gJycsIGxlZ2VuZCA9IFRSVUUpDQojIG1pc3NtYXAoSVNUX1JQUElfTU9ERUxfQ0csIGNvbD1jKCdyZWQnLCAnZ3JlZW4nKSwgeS5hdD0xLCB5LmxhYmVscyA9ICcnLCBsZWdlbmQgPSBUUlVFKQ0KIyB0byBmaWxsIHRoZSBtZWRpYW4gdmFsdWUgaWYgdGhlIG1pc3NpbmcgdmFsdWVzIHdlcmUgaW4gZGF0YXNldA0KIyBJU1RfUlBQSV9NT0RFTCQuLi5baXMubmEoSVNUX1JQUElfTU9ERUwkLi4uKV0gPC0gbWVkaWFuKElTVF9SUFBJX01PREVMJC4uLiwgbmEucm0gPSBUUlVFKQ0KYGBgDQoNCioqTm90ZSoqOiAqVGhlIHN0dWR5IGRvZXNuJ3QgY29uc2lzdCBhbnkgbWlzc2luZyBvYnNlcnZhdGlvbnMuIE9uIHRoZSBzb21lIGxpdGVyYXR1cmUgdGV4dCB0aGF0IGZpbGxpbmcgdGhlIG1pc3NpbmcgdmFsdWVzIHdpdGggbWVkaWFuIHZhbHVlIG9mIHRoZSB2YXJpYWJsZXMuKlwNCg0KDQoNCiMjIyMgU2hvdyBUaGUgQ29ycmVsYXRpb25cDQoNCg0KQ29ycmVsYXRpb24gdGFibGUgaW5jbHVkaW5nIHJlbGF0ZWQgY29lZmZpY2llbnRzIGJlbG93IGluIHRoZSBjaGFydC5cDQoNCg0KDQpgYGB7ciBDb3JyZWxhdGlvbiBUYWJsZSBQcmljZSB9DQojIGNvZWZmaWNpZW50cyB0YWJsZXMNCnJlc19tbiA8LSBjb3Ioc2VsZWN0KElTVF9SUFBJX01PREVMLCAtREFURSkpDQpyZXNfbW4gPC0gZGF0YS5mcmFtZShyb3VuZChyZXNfbW4sIDIpKQ0KaGVhZChyZXNfbW4sIG49NikNCmBgYA0KDQpUaGlzIHRhYmxlIHNob3cgdXMgdGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyBiZXR3ZWVuIElzdGFuYnVsIFVuaXQgSG91c2luZyBQcmljZXMgYW5kIHRoZSBvdGhlciB2YXJpYWJsZXMuXA0KDQpUaGUgYmVzdCBjb3JyZWxhdGlvbiBlcXVpdmFsZW50IGluIG9yZGVyIHRvIGV4cGxhaW4gdGhlIGhvdXNpbmcgdW5pdCBwcmljZXMgOlwNCg0KDQoxLiBSTlRfQ1BJIDogMC45Ng0KDQoyLiBJU1RfQ1BJIDogMC45Mw0KDQozLiBVU0RfUlQgOiAwLjg4DQoNCjQuIFRSX1BQSSA6IDAuODMNCg0KNS4gTkVNUF9SVCA6IDAuNjQNCg0KNi4gSVNUX0ZHUl9TTCA6IDAuNjQNCg0KNy4gTUdfUlQgOiAwLjU5DQoNCjguIElTVF9NUlRHX1NMIDogLTAuNTUNCg0KOS4gSVNUX09DQ1BfUFRfOSA6IDAuNDQNCg0KMTAuIENOU1RSX1RSU1QgOiAtMC4zNw0KDQoxMS4gSVNUX0NOU1RfUFQgOiAtMC4xNlwNCg0KDQoNClRoZSBJbmRleCB3aGljaCBhcmUgUmVudCBDb25zdW1lciBQcmljZSBJbmRleCwgSXN0YW5idWwgQ29uc3VtZXIgUHJpY2UgSW5kZXgsIFVTRCBSYXRlIGFuZCBUdXJrZXkgUHJvZHVjZXIgUHJpY2UgSW5kZXggYWZmZWN0aW5nIFRoZSBIb3VzaW5nIFVuaXQgUHJpY2VzIHZlcnkgc3Ryb25nbHkgY29ycmVsYXRlZC4gU28gdGhhdCB0cnkgdG8gZmluZCB0aGUgYmVzdCBtb2RlbCBpbiB0aGlzIHN0dWR5LCBpbmNsdWRlIHN0cm9uZyBjb3JyZWxhdGVkIHZhcmlhYmxlcyBpbiB0aGUgbW9kZWwgb24gbmV4dCBwYXJhZ3JhcGhzLlwNCg0KDQoNCmBgYHtyIENvcnJlbGF0aW9uIFRhYmxlIENoYW5nZXMgfQ0KcmVzX2NnPC0gY29yKHNlbGVjdChJU1RfUlBQSV9NT0RFTF9DRywgLURBVEUpKQ0KcmVzX2NnIDwtIGRhdGEuZnJhbWUocm91bmQocmVzX2NnLCAyKSkNCmhlYWQocmVzX2NnLCBuPTEpDQpgYGANCg0KVGhpcyBzdHVkeSBhbHNvIHByb3ZlZCB0aGF0IHRoZSBtYXJrZXIgb2YgUHJpY2UgYW5kIFByaWNlIEluZGV4IGlzIHBvc2l0aXZlIGNvcnJlbGF0ZWQgYnV0IGZpcnN0IGNhc2UgVW5pdCBQcmljZSBhbmQgUHJpY2UgSW5kZXggY29ycmVsYXRlZCBlcXVhbCwgVGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IGJldHdlZW4gVW5pdCBQcmljZSBDaGFuZ2VzIGFuZCBQcm9wZXJ0eSBQcmljZSBJbmRleCBDaGFuZ2VzIG5lYXJseSAwLjYyLCBkaWZmZXJlbnQgZnJvbSBlYWNoIG90aGVycy5cDQoNCg0KDQpgYGB7ciBDb3JyZWxhdGlvbiBQbG90IH0NCiMjIHBsb3QgdGhlIGNvcnJlbGF0aW9ucw0KY29ycnBsb3QoY29yKHNlbGVjdChJU1RfUlBQSV9NT0RFTCwgLURBVEUpKSwgDQogICAgICAgICBtZXRob2QgPSAic3F1YXJlIiwgdHlwZSA9ICJ1cHBlciIsIHNpZy5sZXZlbCA9IC4wMSkNCmBgYA0KDQpgYGB7ciBDb3JyZWxhdGlvbiBQbG90IENoYW5nZXMgfQ0KI2NvcnJwbG90KGNvcihzZWxlY3QoSVNUX1JQUElfTU9ERUxfQ0csIC1EQVRFKSksIA0KIyAgICAgICAgIG1ldGhvZCA9ICJzcXVhcmUiLCBhZGRyZWN0ID0gMiwgc2lnLmxldmVsID0gLjAxLCB0eXBlICM9ICJ1cHBlciIpDQpgYGANCg0KDQoxLiBUaGUgbWFpbiB2YWx1ZSdzIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IHdhcyB+IDEuMDAgYnV0IGluIHRoaXMgY2FzZSB0aGUgbW9udGhseSBjaGFuZ2VzIGRpZmZlcmVudCB0aGFuIGVhY2ggb3RoZXJzICB3aGVuIGNvbnNpZGVyZWQgdGhlIGFjdHVhbCB2YWx1ZXMsIHRoZSBtb250aGx5IGNoYW5nZSdzIGNvZWZmaWNpZW50cyBkaWZmZXJlbnQgZnJvbSBtYWluIHZhbHVlcy4gRmlyc3QsIHdlIGxvb2sgdXAgdGhlIFVuaXQgUHJpY2UgYW5kIFByb3BlcnR5IFByaWNlIEluZGV4J3MgY29lZmZpY2llbnQgaXMgYXBwcm94aW1hdGVseSB+IDEwMCUgYnV0IHdlIGxvb2sgdGhlIG1vbnRobHkgY2hhbmdlIG9mIHRoZSBib3RoIHZhcmlhYmxlcyBjb2VmZmljaWVudCBpcyB+NjIlLCBTbyB3aGVuIHdlIGNvbnNpZGVyIHdoeSB0aGUgbW9udGhseSBjaGFuZ2VzIGRpZmZlcmVudCB0aGFuIG1haW4gdmFsdWVzLlwNCg0KDQpUaGlzIHR3byBtYWluIGRlcGVuZGVudCB2YXJpYWJsZXMgaXMgdGhlIHNhbWUuIEl0IGNhbiBiZSBleHBsYWluZWQgdGhhdCBQcmljZSBJbmRleCBpcyBwdWJsaXNoaW5nIGFmdGVyIFRoZSBVbml0IFByaWNlcyBtYXliZSAxLTIgbW9udGgsIFByaWNlIEluZGV4IGNhbiBiZSBpbmZsdWVuY2VkIGJ5IHRoZSBvdGhlciB0aGluZ3MuIEFjY29yZGluZyB0byBob3VzaW5nIG1hcmtldCB0aGUgaW5kZXggcHVibGlzaGluZyBhZnRlciAxIGFuZCAyIG1vbnRocyBwdWJsaXNoZWQgdW5pdCBwcmljZXMgYW5kIEluZGV4IGJlIGFmZmVjdGluZyBmcm9tIG90aGVyIG1haW4gSW5kZXggbGlrZSBSZW50LCBDUEksIFBQSSBldGMuXA0KDQoNCjIuIFNlY29uZGx5LCB3ZSBzaG91bGQgbG9vayB0aGUgQ29uc3RydWN0aW9uLU9jY3VwYXRpb25hbCBQZXJtaXRzIHRoZSBiZXN0IGNvcnJlbGF0aW9uIHdpdGggSG91c2luZyBQcmljZXMgaXMNCg0KKyBUaGUgZGlyZWN0IGFuZCBub3QgcG9zdHBvbmVkIHZhbHVlIG9mIENvbnN0cnVjdGlvbiBQZXJtaXRzIH4gLTE2JQ0KKyBIZWxkIG92ZXIgdmFsdWUgZm9yIDkgbW9udGhzIG9mIE9jY3VwYXRpb25hbCBQZXJtaXRzIH4gNDQlXA0KDQoqU28sIEl0IHdvdWxkIGJlIHRoaW5rIHRoYXQgd2hlbiBhIGNvbnN0cnVjdGlvbiBzdGFydCBhbmQgYWxsIHBlcm1pdHMgYmUgZ2V0ICwgaG93IGxvbmcgd2lsbCB0aGlzIHByZS1jb25zdHJ1Y3Rpb24gYW5kIGNvbnN0cnVjdGlvbiBwcm9jZXNzIGV4dGVuZCBvciB3aGVuIHRoaXMgbmV3IHN1cHBseSBnZXQgaW4gdGhlIG1hcmtldD8gVGhlIHN0dWR5IGFsc28gc2hvdyB0aGF0ICoqSG91c2luZyBNYXJrZXQgUHJpY2VzLCoqIG11Y2ggbW9yZSBpbmZsdWVuY2VkIGJ5IE9jY3VwYXRpb25hbCBQZXJtaXRzIHdoaWNoIHB1Ymxpc2hlZCBkYXRhIGZvcndhcmQgZm9yIDkgbW9udGhzLipcDQoNCg0KDQojIyMjIFNob3dpbmcgVGhlIERlbnNpdHlcDQoNCmBgYHtyIERlbnNpdHkgUGxvdCAxIH0NCmdncGxvdGx5KElTVF9SUFBJX01PREVMICU+JQ0KICAgICAgICAgICAgIGdncGxvdChhZXMoSVNUX1BSQykpICsNCiAgICAgICAgICAgICBzdGF0X2RlbnNpdHkoKSArDQogICAgICAgICAgICAgdGhlbWVfbGlnaHQoKSkNCmBgYA0KDQpgYGB7ciBEZW5zaXR5IFBsb3QgMiB9DQpnZ3Bsb3RseShJU1RfUlBQSV9NT0RFTF9DRyU+JQ0KICAgICAgICAgICAgIGdncGxvdChhZXMoSVNUX1BSQykpICsNCiAgICAgICAgICAgICBzdGF0X2RlbnNpdHkoKSArDQogICAgICAgICAgICAgdGhlbWVfbGlnaHQoKSkNCmBgYA0KDQogDQoNClRoZSBQcm9wZXJ0eSBQcmljZSBoYXMgdHdvIG1ham9yIHJhbmdlIC1iaW1vZGFsIGRpc3RyaWJ1dGlvbi0gb25lIG9mIHRoZSBiZXR3ZWVuIDU1LTYwLCB0aGUgb3RoZXIgaXMgOTUtMTAwIGJlY2F1c2Ugb2YgdGhlIHRpbWUgcHJvY2VzcyAuXA0KUHJpY2VzIGFsd2F5cyBnZXR0aW5nIGluY3JlYXNlIHRpbWUgdG8gdGltZSBhbmQgYWxzbyB0aGUgbW9udGhseSBwcmljZSBjaGFuZ2VzIGhhdmUgb25lIG1vZGFsIGRpc3RyaWJ1dGlvbi4gSXQgY2FuIGJlIGVhc2lseSByZWFjaCBtb2QsIG1lZGlhbiwgbWVhbiB2YWx1ZXMgc2hvdyBpbiAiRml2ZSBOdW1iZXIgU3VtbWFyeSBzZWN0aW9uIi5cDQoNCg0KSXN0YW5idWwgSG91c2luZyBQcmljZSBtb250aGx5IGNoYW5nZSBoYXMgb25lIG1vZGFsLG5vcm1hbCBkaXN0cmlidXRpb24uIFNob3dpbmcgVGhlIEZpdmUgTnVtYmVyIFN1bW1hcnkgb2YgUHJpY2UgYW5kIFByaWNlIENoYW5nZSBiZWxvd2luZyBjaGFydC5cDQoNCg0KYGBge3IgU3VtbWFyeSAzIH0NCnN1bW1hcnkoSVNUX1JQUElfTU9ERUwkSVNUX1BSQykNCmBgYA0KDQpgYGB7ciBTdW1tYXJ5IDQgfQ0Kc3VtbWFyeShJU1RfUlBQSV9NT0RFTF9DRyRJU1RfUFJDKQ0KYGBgDQoNCg0KIyMjIyBTZWVpbmcgVGhlIENvcnJlbGF0aW9uIFBsb3RcDQoNCkluIG9yZGVyIHRvIHBsb3QgYWxsIHZhcmlhYmxlcyByZWxhdGVkIHdpdGggdGhlIEhvdXNpbmcgUHJpY2VzIDpcDQoNCg0KDQpgYGB7ciBDb3JyZWxhdGlvbiBSZWxhdGlvbnNoaXAgfQ0KDQpJU1RfUlBQSV9NT0RFTCAlPiUNCiAgICBzZWxlY3QoYyhJU1RfUFJDLCBNR19SVCwgSVNUX0ZHUl9TTCwgSVNUX1BSUF9TTCwgDQogICAgICAgICAgICAgSVNUX01SVEdfU0wsIENOU1RSX1RSU1QsIFJOVF9DUEksIA0KICAgICAgICAgICAgIElTVF9DUEksIFRSX1BQSSwgVVNEX1JULCANCiAgICAgICAgICAgICBORU1QX1JULCBJU1RfQ05TVF9QVCwgSVNUX09DQ1BfUFRfOSkpICU+JQ0KICAgIG1lbHQoaWQudmFycyA9ICJJU1RfUFJDIikgJT4lDQogICAgZ2dwbG90KGFlcyh4ID0gdmFsdWUsIHkgPSBJU1RfUFJDLCBjb2xvdXIgPSB2YXJpYWJsZSkpICsNCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC43KSArDQogICAgc3RhdF9zbW9vdGgoYWVzKGNvbG91ciA9ICJibGFjayIpKSArDQogICAgZmFjZXRfd3JhcCh+IHZhcmlhYmxlLCBzY2FsZXMgPSAiZnJlZSIsIG5jb2wgPSAzKSArDQogICAgbGFicyh4ID0gIlZhcmlhYmxlIFZhbHVlIiwgDQogICAgICAgICB5ID0gIklzdGFuYnVsIEhvdXNpbmcgUHJpY2UiKSArDQogICAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KYGBge3IgfQ0KI0lTVF9SUFBJX01PREVMX0NHICU+JQ0KIyAgICBzZWxlY3QoYyhJU1RfUFJDLCBNR19SVCwgSVNUX0ZHUl9TTCwgDQojICAgIElTVF9QUlBfU0wsIElTVF9NUlRHX1NMLCBDTlNUUl9UUlNULCANCiMgICAgUk5UX0NQSSwgSVNUX0NQSSwgVFJfUFBJLCBVU0RfUlQsIA0KIyAgICBORU1QX1JULCBJU1RfQ05TVF9QVCwgSVNUX09DQ1BfUFRfOSkpICU+JQ0KIyAgICBtZWx0KGlkLnZhcnMgPSAiSVNUX1BSQyIpICU+JQ0KIyAgICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSwgeSA9IElTVF9QUkMsIGNvbG91ciA9IHZhcmlhYmxlKSkgKw0KIyAgICBnZW9tX3BvaW50KGFscGhhID0gMC43KSArDQojICAgIHN0YXRfc21vb3RoKGFlcyhjb2xvdXIgPSAiYmxhY2siKSkgKw0KIyAgICBmYWNldF93cmFwKH4gdmFyaWFibGUsIHNjYWxlcyA9ICJmcmVlIiwgbmNvbCA9IDMpICsNCiMgICAgbGFicyh4ID0gIlZhcmlhYmxlIFZhbHVlIiwNCiMgICAgeSA9ICJJc3RhbmJ1bCBIb3VzaW5nIFByaWNlIENoYW5nZSIpICsNCiMgICAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KDQpUaGUgY29ycmVsYXRpb24gYmV0d2VlbiBhbGwgdmFyaWFibGVzICpQb3NpdGl2ZSAmIE5lZ2F0aXZlIENvcnJlbGF0aW9uKiB3b3VsZCBlYXNpbHkgc2hvd2VkIGFib3ZlIGEgcGxvdCB3aXRoIElzdGFuYnVsIEhvdXNpbmcgUHJpY2VzLlwNCg0KDQoqKlBvc2l0aXZlIENvcmVsYXRpb24qKnwgKipOZWdhdGl2ZSBDb3JyZWxhdGlvbioqDQotLS0tLS0tLS0tLS0tLS0tLS0tICAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLQ0KTW9ydGdhZ2UgUmF0ZXMgICAgICAgICB8IENvbnN0cnVjdGlvbiBUcnVzdCBJbmRleA0KRm9yZWlnbmVyIFNhbGVzICAgICAgICB8IE1vcnRnYWdlIFNhbGVzDQpSZW50IENQSSAgICAgICAgICAgICAgIHwNClVTRCBSYXRlICAgICAgICAgICAgICAgfA0KVFIgUFBJICAgICAgICAgICAgICAgICB8DQpJU1QgQ1BJICAgICAgICAgICAgICAgIHwNCk5FTVAgUmF0ZSAgICAgICAgICAgICAgfA0KDQoNClwNCg0KDQpVTkVNUCByYXRlIGlzIGFsc28gZXhwZWN0aW5nIG5lZ2F0aXZlIGNvcnJlbGF0aW9uIGJlY2F1c2UgdGhlIHB1cmNoYXNpbmcgcG93ZXIgaXMgZGVjcmVhc2luZyBzbyBhbnlvbmUgd291bGQgbm90IHdhbnQgdG8gYnV5IGEgaG91c2UgdGhpcyBtZWFucyBkZW1hbmQgd2lsbCBkZWNyZWFzZSBhbmQgcHJpY2Ugc2hvdWxkIGJlIGV4cGVjdGluZyBkb3duLiBJbiB0aGlzIGNhc2UgdGhpcyBub3QgZ28gdGhyb3VnaCB3aGF0IHdlIGV4cGVjdGluZy4gDQoNCiMjIyMgQnVpbGRpbmcgQSBNb2RlbCAoVHJhaW4tVGVzdClcDQoNCiMjIyMjIFNldHRpbmcgYSBTZWVkIFJhbmRvbSBOdW1iZXJcDQoNClNlZWQgbnVtYmVyIHNob3VsZCBiZSBzZWxlY3RlZCB0byBkZXRlcm1pbmUgdGhlIHNhbWUgcmVzdWx0cywgYWNjdXJhY3ksIGVycm9ycyBldmVyeSBydW4gY29tbWFuZC4gSW4gdGhpcyBzdHVkeSwgMjAxOSBpcyBzcGVjaWZpZWQuXA0KDQpgYGB7ciB9DQojc2V0LnNlZWQoMjAxOSkNCiNzcGxpdCA8LSBzYW1wbGUuc3BsaXQoSVNUX1JQUElfTU9ERUwsIFNwbGl0UmF0aW8gPSAwLjcwKQ0KI3RyYWluX21uIDwtIHN1YnNldChJU1RfUlBQSV9NT0RFTCwgc3BsaXQgPT0gRkFMU0UpDQojdGVzdF9tbiAgPC0gc3Vic2V0KElTVF9SUFBJX01PREVMLCBzcGxpdCA9PSBGQUxTRSkNCiNzZXQuc2VlZCgyMDE5KQ0KI3NwbGl0IDwtIHNhbXBsZS5zcGxpdChJU1RfUlBQSV9NT0RFTF9DRywgU3BsaXRSYXRpbyA9IDAuNzApDQojdHJhaW5fY2cgPC0gc3Vic2V0KElTVF9SUFBJX01PREVMX0NHLCBzcGxpdCA9PSBUUlVFKQ0KI3Rlc3RfY2cgIDwtIHN1YnNldChJU1RfUlBQSV9NT0RFTF9DRywgc3BsaXQgPT0gRkFMU0UpDQpgYGANClNwbGl0IGlzIG1lYW5pbmcgdGhlIHBvcnRpb24gb2YgdGhlIHRyYWluaW5nIGRhdGEuIEZvciBhIHN0dWR5IHRyYWluIHNldCBkZXRlcm1pbmVkIDAuNzAgb2YgYWxsIGRhdGEgc2V0IHRoaXMgc2hvdWxkIGJlIGluY3JlYXNlIGluIHNtYWxsIGRhdGEgc2V0cyBhcyB3ZWxsIHRlc3Qgc2V0IHNwZWNpZmllZCAwLjMwXA0KDQoqKk5vdGVzIDogU3BsaXQgYW5kIHNlZWQgbnVtYmVyIGRpZG4ndCB1c2UgZm9yIHRoZSBtb2RlbCB3aHkgdGhlIG1vZGVsIGlzIHdlYWsgZm9yIG9ic2VydmF0aW9ucyB+IDcyKipcDQoNCg0KIyMjIyMgQnVpbGRpbmcgRGlmZmVyZW50IE1vZGVscyBhbmQgU2VlIFJlc2lkdWFsc1wgDQoNCg0KYGBge3IgTW9kZWwgMSB9DQptb2RlbDFfbW4gPC0gbG0oSVNUX1BSQyB+IE1HX1JUICsgSVNUX0ZHUl9TTCArICANCiAgICAgICAgICAgICAgICAgICAgSVNUX01SVEdfU0wgKyBDTlNUUl9UUlNUICsNCiAgICAgICAgICAgICAgICAgICAgUk5UX0NQSSArIFVTRF9SVCArIA0KICAgICAgICAgICAgICAgICAgICBJU1RfQ05TVF9QVCArICBJU1RfT0NDUF9QVF85ICwgDQogICAgICAgICAgICAgICAgZGF0YSA9IElTVF9SUFBJX01PREVMKQ0Kc3VtbWFyeShtb2RlbDFfbW4pDQpgYGANCg0KDQpNb2RlbCdzIFAtdmFsdWVzIG5vdCBnb29kIHdoYXQgZXhwZWN0aW5nLCBNb2RlbC0xIHNheXMgdXMgb25seSBSZW50IENQSSBpcyBhZmZlY3RpbmcgUHJpY2UsIFRoZSBkYXRhIGluY2x1ZGluZyBib3RoIG9uZSBkaWdpdCBudW1iZXJzIGFuZCBmb3VyJmZpdmUgZGlnaXQgbnVtYmVycy4gQW4gYWx0ZXJuYXRpdmUgc29sdXRpb24gdG8gZ2V0IHJpZCBvZiBiaWcgbnVtYmVycyB0byBzdGFydCBsb2dhcml0aG0gcHJvY2VzcyBmb3IgYmlnIG51bWJlcnMuXA0KQnVpbHQgYSBuZXcgb25lIG1vcmUgbW9kZWwgd2hpY2ggaXMgKipNb2RlbC0yIHdpdGggbG9nYXJpdGhtIHByb2Nlc3MuKipcDQoNCg0KYGBge3IgTW9kZWwgMiB9DQptb2RlbDJfbW4gPC0gbG0obG9nMTAoSVNUX1BSQykgfiBNR19SVCArIGxvZzEwKElTVF9GR1JfU0wpICsgIA0KICAgICAgICAgICAgICAgICAgICBsb2cxMChJU1RfTVJUR19TTCkgKyBDTlNUUl9UUlNUICsgUk5UX0NQSSArIFVTRF9SVCArIA0KICAgICAgICAgICAgICAgICAgICBsb2cxMChJU1RfQ05TVF9QVCkgKyAgbG9nMTAoSVNUX09DQ1BfUFRfOSkgLCANCiAgICAgICAgICAgICAgICBkYXRhID0gSVNUX1JQUElfTU9ERUwpDQpzdW1tYXJ5KG1vZGVsMl9tbikNCmBgYA0KDQoNCioqTW9kZWwtMioqIGluY3JlYXNlZCB0aGUgcC12YWx1ZSBvZiB2YXJpYWJsZXMuIFdoZW4gbG9va2luZyBtb2RlbC0yLCB0aGVyZSBhcmUgZm91ciBkaWZmZXJlbnQgdmFyaWFibGVzIGluIGNvbmZpZGVuY2UgcC12YWx1ZXMgYXMgd2VsbCBVU0QgUmF0ZSBjbG9zZSB0byBsaW5lLlwNCg0KSW4gTW9kZWwtMiB1c2VkIGxvZ2FyaXRobSBvbiB0aHJlZSBvciBtb3JlIGRpZ2l0IHZhbHVlcy5cDQoNCg0KYGBge3IgTW9kZWwgMyB9DQptb2RlbDNfbW4gPC0gbG0obG9nMTAoSVNUX1BSQykgfiBsb2cxMChNR19SVCkgKyBsb2cxMChJU1RfRkdSX1NMKSArICANCiAgICAgICAgICAgICAgICAgICAgbG9nMTAoSVNUX01SVEdfU0wpICsgbG9nMTAoQ05TVFJfVFJTVCkgKyANCiAgICAgICAgICAgICAgICAgICAgbG9nMTAoUk5UX0NQSSkgKyBsb2cxMChVU0RfUlQpICsgDQogICAgICAgICAgICAgICAgICAgIGxvZzEwKElTVF9DTlNUX1BUKSAgLCANCiAgICAgICAgICAgICAgICBkYXRhID0gSVNUX1JQUElfTU9ERUwpDQpzdW1tYXJ5KG1vZGVsM19tbikNCmBgYA0KDQoNCioqSW4gTW9kZWwtMyoqLCBhbGwgdmFyaWFibGVzIHJlZHVjZWQgd2l0aCBsb2dhcml0aG0gc28gdGhhdCBkZWNyZWFzZSBkaWdpdHMgYnV0IGluIHRoaXMgbW9kZWwgdGhlcmUgaXNuJ3QgZW5vdWdoIGNvbmZpZGVuY2UgdGhhbiBNb2RlbC0yLiBTbyBrZWVwIGNvbnRpbnVvdXMgd2l0aCBNb2RlbC0yIGFuZCByZW1vdmUgdGhlIGhpZ2hlc3QgcC12YWx1ZSB3aGljaCBpcyBtb3J0Z2FnZSByYXRlcyBwbHVzIG1vcnRnYWdlIHNhbGVzLiBBZGQgdGhlIHByb3BlcnR5IHNhbGVzIHJhdGhlciB0aGFuIG1vcnRnYWdlIHNhbGVzLlwNCg0KDQpgYGB7ciBNb2RlbCA0IH0NCm1vZGVsNF9tbiA8LSBsbShsb2cxMChJU1RfUFJDKSB+IGxvZzEwKElTVF9GR1JfU0wpICsgIA0KICAgICAgICAgICAgICAgICAgICBsb2cxMChJU1RfUFJQX1NMKSArIENOU1RSX1RSU1QgKyBSTlRfQ1BJICsgVVNEX1JUICsgDQogICAgICAgICAgICAgICAgICAgIGxvZzEwKElTVF9DTlNUX1BUKSArICBsb2cxMChJU1RfT0NDUF9QVF85KSAsIA0KICAgICAgICAgICAgICAgIGRhdGEgPSBJU1RfUlBQSV9NT0RFTCkNCnN1bW1hcnkobW9kZWw0X21uKQ0KYGBgDQoNCg0KV2hlbiBjb25zaWRlcmVkIHRoZSBDb25zdHJ1Y3Rpb24gVHJ1c3QgSW5kZXgncyBwLXZhbHVlIHNvIGhpZ2hlciB0aGFuIG90aGVycy4gSXQgY2FuIGJlIHJlbW92ZSBmcm9tIG1vZGVsLCB0cnkgdG8gZmluZCBtb3JlIGFjY3VyYWN5IG1vZGVsIGluIE1vZGVsLTUuXA0KDQoNCmBgYHtyIE1vZGVsIDUgfQ0KbW9kZWw1X21uIDwtIGxtKGxvZzEwKElTVF9QUkMpIH4gbG9nMTAoSVNUX0ZHUl9TTCkgKyAgDQogICAgICAgICAgICAgICAgICAgIGxvZzEwKElTVF9QUlBfU0wpICArIFJOVF9DUEkgKyBVU0RfUlQgKyANCiAgICAgICAgICAgICAgICAgICAgbG9nMTAoSVNUX0NOU1RfUFQpICsgIGxvZzEwKElTVF9PQ0NQX1BUXzkpICwgDQogICAgICAgICAgICAgICAgZGF0YSA9IElTVF9SUFBJX01PREVMKQ0Kc3VtbWFyeShtb2RlbDVfbW4pDQpgYGANCg0KDQoqKk1vZGVsLTUqKiBnb29kIGNvcnJlbGF0ZWQgdG8gZXhwbGFpbiB0aGUgcHJpY2VzIGJ1dCBJdCBpcyBub3QgZW5vdWdoIGJlY2F1c2Ugb2YgdGhlIGJpZyBwLXZhbHVlcy4gSW4gbW9kZWwtNiwgZ2V0IHJpZCBvZiB0aGUgT2NjdXBhdGlvbmFsIFBlcm1pdHMuXA0KDQoNCmBgYHtyIE1vZGVsIDYgfQ0KbW9kZWw2X21uIDwtIGxtKGxvZzEwKElTVF9QUkMpIH4gbG9nMTAoSVNUX0ZHUl9TTCkgKyAgDQogICAgICAgICAgICAgICAgICAgIGxvZzEwKElTVF9QUlBfU0wpICArIFJOVF9DUEkgKyBVU0RfUlQgKyANCiAgICAgICAgICAgICAgICAgICAgbG9nMTAoSVNUX0NOU1RfUFQpICAsIA0KICAgICAgICAgICAgICAgIGRhdGEgPSBJU1RfUlBQSV9NT0RFTCkNCnN1bW1hcnkobW9kZWw2X21uKQ0KYGBgDQoNCg0KV2hlbiBTdXBwbHktRGVtYW5kIEVxdWlsaWJyaXVtIGNvbnNpZGVyZWQ6IFByb3BlcnR5IFNhbGVzIGV4cGVjdGluZyBpbmNyZWFzZSwgUHJpY2Ugd291bGQgYmUgZ2V0IGhpZ2hlci4gQmVjYXVzZSBvZiB0aGUgY29uZmlkZW5jZSBsZXZlbCBvZiBQcm9wZXJ0eSBTYWxlcyB0aGUgdmFyaWFibGUncyBtYXJrZXIgc2F5IHVzIHRoZSBuZWdhdGl2ZSBzaXR1YXRpb24uIEluIE1vZGVsLTcsIHJlbW92ZWQgdGhlIFByb3BlcnR5IFNhbGVzLlwNCg0KDQoNCmBgYHtyIE1vZGVsIDcgfQ0KbW9kZWw3X21uIDwtIGxtKGxvZzEwKElTVF9QUkMpIH4gbG9nMTAoSVNUX0ZHUl9TTCkgKyAgDQogICAgICAgICAgICAgICAgICAgIFJOVF9DUEkgKyBVU0RfUlQgKyANCiAgICAgICAgICAgICAgICAgICAgbG9nMTAoSVNUX0NOU1RfUFQpICAsIA0KICAgICAgICAgICAgICAgIGRhdGEgPSBJU1RfUlBQSV9NT0RFTCkNCnN1bW1hcnkobW9kZWw3X21uKQ0KYGBgDQoNCg0KKipNb2RlbC03KiogaXMgZmluYWwgb3V0Y29tZSBpbiB3aGljaCBtb3JlIGNvbXByZWhlbnNpdmUgYW5kIG1lYW5pbmdmdWxseSB0aGFuIG90aGVyIG1vZGVscy4gVGhlIG1vZGVsIHByb3ZlIHRoYXQgOg0KDQoqIElmIFRvdGFsIEZvcmVpZ25lciBTYWxlIGluY3JlYXNlIHRoYW4gUHJpY2Ugd291bGQgYmUgaGlnaGVyDQoqIElmIFJlbnQgQ29uc3VtZXIgUHJpY2UgSW5kZXggd291bGQgYmUgaGlnaGVyIHRoYW4gUHJpY2UgZ2V0IGluY3JlYXNlDQoqIFdoZW4gaXQgY29tZSB0byBVU0QgUmF0ZSwgY29uc2lkZXJlZCB0aGUgSG91c2luZyBNYXJrZXQgYXQgdGhpcyBtb21lbnQuIFVTRCBjdXJyZW5jeSBleHRyZW1lbHkgaGlnaCBhbmQgSG91c2luZyBQcmljZXMgZ2V0dGluZyBkZWNyZWFzZS4gU28gdGhpcyBtb2RlbCBhY3R1YWxseSBwcm92ZSB0aGF0Lg0KKiBDb25zdHJ1Y3Rpb24gUGVybWl0cyBhZmZlY3RpbmcgaG91c2luZyBwcmljZXMgcG9zaXRpdmUuDQoNCg0KDQoqIEFub3RoZXIgZGlmZmVyZW50IG1vZGVsIGZvciBleHBsYWluaW5nICoqTW9ydGdhZ2UgU2FsZXMqKiA6XA0KDQoNCg0KDQpgYGB7ciBNb2RlbCA4IH0NCm1vZGVsOF9tbiA8LSBsbShsb2cxMChJU1RfTVJUR19TTCkgfiBNR19SVCArIGxvZzEwKElTVF9GR1JfU0wpICsgDQogICAgICAgICAgICAgICAgICAgIGxvZzEwKElTVF9QUkMpICsgSVNUX1JQUEkgKw0KICAgICAgICAgICAgICAgICAgICBDTlNUUl9UUlNUICsgUk5UX0NQSSArIElTVF9DUEkgKyANCiAgICAgICAgICAgICAgICAgICAgVFJfUFBJICsgVVNEX1JUICsgTkVNUF9SVCArIA0KICAgICAgICAgICAgICAgICAgICBsb2cxMChJU1RfQ05TVF9QVCkgKyAgDQogICAgICAgICAgICAgICAgICAgIGxvZzEwKElTVF9PQ0NQX1BUXzkpICwgDQogICAgICAgICAgICAgICAgZGF0YSA9IElTVF9SUFBJX01PREVMKQ0Kc3VtbWFyeShtb2RlbDhfbW4pDQpgYGANCg0KDQpUaGUgbW9kZWwgY2FuJ3QgZXhwbGFpbiB3aGF0IHRoZSBzdHVkeSB3YW50LiBSZW1vdmUgdGhlIGhpZ2ggcC12YWx1ZXMgd2hpY2ggYXJlIElTVF9SUFBJIGFuZCBDTlNUUl9UUlNUIGZyb20gbW9kZWwuXA0KDQoNCmBgYHtyIE1vZGVsIDkgfQ0KbW9kZWw5X21uIDwtIGxtKGxvZzEwKElTVF9NUlRHX1NMKSB+IE1HX1JUICsgbG9nMTAoSVNUX0ZHUl9TTCkgKyANCiAgICAgICAgICAgICAgICAgICAgbG9nMTAoSVNUX1BSQykgKyANCiAgICAgICAgICAgICAgICAgICAgUk5UX0NQSSArIElTVF9DUEkgKyANCiAgICAgICAgICAgICAgICAgICAgVFJfUFBJICsgVVNEX1JUICsgTkVNUF9SVCArIA0KICAgICAgICAgICAgICAgICAgICBsb2cxMChJU1RfQ05TVF9QVCkgKyAgDQogICAgICAgICAgICAgICAgICAgIGxvZzEwKElTVF9PQ0NQX1BUXzkpICwgDQogICAgICAgICAgICAgICAgZGF0YSA9IElTVF9SUFBJX01PREVMKQ0Kc3VtbWFyeShtb2RlbDlfbW4pDQojIyBlc3RpbWF0ZXMgYXJlIHRoZSBjb2VmZmljaWVudCBvZiB0aGUgdmFyaWFibGVzIGluIGEgZXF1YXRpb24uIHkgPSBheCArIGJ5ICsgY3ogDQpgYGANCg0KDQpSZW1vdmUgZnJvbSBtb2RlbCBVU0RfUlQsIE5FTVBfUlQsIENOU1QgJiBPQ0NQIFBlcm1pdHMsIFJOVF9DUElcDQoNCg0KYGBge3IgTW9kZWwgMTAgfQ0KbW9kZWwxMF9tbiA8LSBsbShsb2cxMChJU1RfTVJUR19TTCkgfiBNR19SVCArIGxvZzEwKElTVF9GR1JfU0wpICsgDQogICAgICAgICAgICAgICAgICAgIGxvZzEwKElTVF9QUkMpICsgDQogICAgICAgICAgICAgICAgICAgIElTVF9DUEkgKyANCiAgICAgICAgICAgICAgICAgICAgVFJfUFBJICwgDQogICAgICAgICAgICAgICAgZGF0YSA9IElTVF9SUFBJX01PREVMKQ0Kc3VtbWFyeShtb2RlbDEwX21uKQ0KYGBgDQoNCg0KKkZpbmFsIHN0ZXAgSVNUX1BSQyBhbmQgSVNUX0NQSSBhcmUgbm90IGluIGNvbmZpZGVuY2UgcC12YWx1ZSwgcmVtb3ZlIGZyb20gbW9kZWwuKlwNCg0KDQpgYGB7ciBNb2RlbCAxMSB9DQptb2RlbDExX21uIDwtIGxtKGxvZzEwKElTVF9NUlRHX1NMKSB+IE1HX1JUICsgbG9nMTAoSVNUX0ZHUl9TTCkgKyAgDQogICAgICAgICAgICAgICAgICAgIFRSX1BQSSAsIA0KICAgICAgICAgICAgICAgIGRhdGEgPSBJU1RfUlBQSV9NT0RFTCkNCnN1bW1hcnkobW9kZWwxMV9tbikNCmBgYA0KDQpcDQoNCg0KKipGaW5hbCBvdXRjb21lKiogc2hvdyB1cyBQcm9wZXJ0eSBTYWxlcyB3aXRoIE1vcnRnYWdlIGlzIGhpZ2hseSBuZWdhdGl2ZSBjb3JyZWxhdGVkIHdpdGggTW9ydGdhZ2UgUmF0ZXMgd2hhdCBJdCBpcyBlYXNpbHkgZXhwZWN0ZWQuDQpUdXJrZXkgUHJvZHVjZXIgUHJpY2UgSW5kZXggYWxzbyBuZWdhdGl2ZSBjb3JyZWxhdGVkIHdpdGggTW9ydGdhZ2UgU2FsZXMgYnV0IEZvcmVpZ25lciBTYWxlcyBzdHJvbmdseSBjb3JyZWxhdGVkIHdpdGggRm9yZWlnbmVyIFNhbGVzLiBXaGVuIEZvcmVpZ25lciBTYWxlcyBpbmNyZWFzZSwgTW9ydGdhZ2UgU2FsZXMgYWxzbyBpbmNyZWFzaW5nLlwNCg0KDQpGb3IgdGhpcyBzdHVkeSBjcmVhdGVkIGFuZCBidWlsdCBkaWZmZXJlbnQgbW9kZWxzLiBGaXJzdCBvZiBhbGwgaW4gTW9kZWwtMSBpbmNsdWRlIGFsbCB2YXJpYWJsZXMgd2hpY2ggaGF2ZSBsb2dpY2FsIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cy5cDQoNCg0KDQoqKkhvdXNpbmcgUHJpY2UgTW9kZWwqKlwNCg0KDQoNCiogQ3JlYXRlZCBtb2RlbCB3aXRoIHRoZSBtb3N0IGxvZ2ljYWwgdmFyaWFibGVzIGluIE1vZGVsLTFcDQoNCg0KKiBFbGltaW5hdGVkIG9uZSBieSBvbmUgYWNjb3JkaW5nIHRvIHRoZSBQLVZhbHVlLlwNCg0KDQoqIEhvdXNpbmcgUHJpY2UgTW9kZWxcIA0KDQoNCg0KJCQgUsKyID0gMC45MSAkJA0KDQpcDQoNCg0KDQoNCiQkIGxvZzEwKEhvdXNpbmdQcmljZSkgPSAwLjA3eGxvZzEwKEZSR05SU0wpKzAuMDAzeFJlbnRDUEktMC4wNXhVU0RSYXRlKzAuMDd4bG9nMTAoQ05TVFBSTVQpKzIuMTc1ICQkDQoNClwNCg0KIA0KKipNb3J0Z2FnZSBTYWxlIE1vZGVsKioNCg0KMS4gTW9kZWwgMTEgaXMgZXhwbGFpbmluZyB0aGUgKipIb3VzaW5nIFNhbGVzIEJ5IFVzaW5nIExvYW4qKiwgYWxsIGJpZyBudW1iZXJzIGxpa2UgdGhvdXNhbmQgcmVkdWNlZCB3aXRoIGxvZzEwLiBUbyBtYW55IGlycmVsZXZhbnQgcC12YWx1ZXMgb2JzZXJ2ZWQgaW4gbW9kZWwgOC4gUmVsYXRlZCBJbmRleCBudW1iZXJzIHJlbW92ZWQgZnJvbSBtb2RlbC4NCg0KMi4gUC12YWx1ZXMgd2hpY2ggaXMgYmlnZ2VyIHRoYW4gMC4wNSBlbGltaW5hdGVkIG9uZSBieSBvbmUgYW5kIHRoZSBmaW5hbCBtb2RlbC4NCg0KMy4gRmluYWwgbW9kZWxcDQoNCiQkUsKyID0gMC44MyQkDQoNClwNCg0KDQoNCiQkIGxvZzEwKFNhbGVzKSA9IDAuMTk3eGxvZzEwKEZSR05SU0wpLTAuMDQ1eE1HUlQtMC4wMDA3eFRSUFBJKzQuMDY0ICQkDQoNClwNCg0KDQpgYGB7ciB9DQojIyMjIyA5LjMuIFJlc2lkZW50aWFsIFByb3BlcnR5IFByaWNlIEluZGV4IE1vbnRobHkgQ2hhbmdlcyAtIENyZWF0aW5nIERpZmZlcmVudCBNb2RlbHMgYW5kIFNlZSBSZXNpZHVhbHMgLSAgDQojbW9kZWwxX2NnIDwtIGxtKElTVF9QUkMgfiBNR19SVCArIElTVF9GR1JfU0wgKyBJU1RfUFJQX1NMICsgSVNUX01SVEdfU0wgKyBDTlNUUl9UUlNUICsgUk5UX0NQSSArIElTVF9DUEkgKyBUUl9QUEkgKyBVU0RfUlQgKyBORU1QX1JUICsgSVNUX0NOU1RfUFQgKyAgSVNUX09DQ1BfUFRfOSAsIGRhdGEgPSB0cmFpbl9jZykNCiNzdW1tYXJ5KG1vZGVsMV9jZykNCg0KI21vZGVsMl9jZyA8LSBsbShJU1RfUFJDIH4gTUdfUlQgKyBJU1RfRkdSX1NMICsgSVNUX1BSUF9TTCArIElTVF9NUlRHX1NMICsgQ05TVFJfVFJTVCArIFJOVF9DUEkgKyBJU1RfQ1BJICsgVFJfUFBJICsgVVNEX1JUICsgTkVNUF9SVCArIElTVF9DTlNUX1BUICsgIElTVF9PQ0NQX1BUXzkgLCBkYXRhID0gdHJhaW5fY2cpDQojc3VtbWFyeShtb2RlbDJfY2cpDQoNCiNtb2RlbDNfY2cgPC0gbG0oSVNUX1BSQyB+IElTVF9GR1JfU0wgKyBJU1RfUFJQX1NMICsgSVNUX01SVEdfU0wgKyBSTlRfQ1BJICsgSVNUX0NQSSArIFRSX1BQSSArIElTVF9DTlNUX1BUICsgIElTVF9PQ0NQX1BUXzkgLCBkYXRhID0gdHJhaW5fY2cpDQojc3VtbWFyeShtb2RlbDNfY2cpDQoNCiNtb2RlbDRfY2cgPC0gbG0oSVNUX1BSQyB+IFJOVF9DUEkgKyBJU1RfRkdSX1NMICwgZGF0YSA9IHRyYWluX2NnKQ0KI3N1bW1hcnkobW9kZWw0X2NnKQ0KDQojVGhpcyBtb2RlbCBpbmNsdWRlIHRoZSBjaGFuZ2UgcmF0ZXMgb2YgSG91c2luZyBVbml0IFByaWNlcyBhbmQgb3RoZXIgdmFyaWFibGVzLiBTbyB0cnkgdG8gZXhwbGFpbiBVbml0IFByaWNlcyB3aXRoIGRpZmZlcmVudCB1bmRlcGVuZGVudCB2YXJpYWJsZXMuDQpgYGANCg0KDQogDQoNCiMjIyMgUmVzaWR1YWxzIC0gT3V0bGllcnNcDQoNCkZvciBhbGwgbW9kZWwgZXJyb3JzIGJlbG93IGluIHRoZSB0YWJsZSBhY2NvcmRpbmcgdG8gQUlDICYgQklDLlwNCg0KYGBge3IgQUlDIC0gQklDIH0NCg0KbGlicmFyeShzdGF0cykNCkFJQyhtb2RlbDFfbW4sIA0KICAgIG1vZGVsMl9tbiwgDQogICAgbW9kZWwzX21uLCANCiAgICBtb2RlbDRfbW4sIA0KICAgIG1vZGVsNV9tbiwgDQogICAgbW9kZWw2X21uLCANCiAgICBtb2RlbDdfbW4sIA0KICAgIG1vZGVsOF9tbiwgDQogICAgbW9kZWw5X21uLCANCiAgICBtb2RlbDEwX21uLA0KICAgIG1vZGVsMTFfbW4pDQoNCkJJQyhtb2RlbDFfbW4sDQogICAgbW9kZWwyX21uLA0KICAgIG1vZGVsM19tbiwNCiAgICBtb2RlbDRfbW4sDQogICAgbW9kZWw1X21uLA0KICAgIG1vZGVsNl9tbiwNCiAgICBtb2RlbDdfbW4sDQogICAgbW9kZWw4X21uLA0KICAgIG1vZGVsOV9tbiwNCiAgICBtb2RlbDEwX21uLA0KICAgIG1vZGVsMTFfbW4pDQpgYGANCg0KDQpSZWxhdGVkIHdpdGggTW9kZWwtNyBSZXNpZHVhbHMsIE91dGxpZXJzIHNob3dlZCBvbiB0aGUgcGxvdC5cDQoNCg0KIA0KDQpgYGB7ciBSZXNpZHVhbHMgfQ0KIyMgbW9kZWwyDQpyZXMxX21uIDwtIHJlc2lkdWFscyhtb2RlbDdfbW4pDQpyZXMxX21uIDwtIGFzLmRhdGEuZnJhbWUocmVzMV9tbikNCmdncGxvdChyZXMxX21uLCBhZXMocmVzMV9tbikpICsgDQogICAgICAgIGdlb21faGlzdG9ncmFtKGZpbGwgPSAnZ3JlZW4nLCBhbHBoYSA9IDAuNSkNCnBsb3QobW9kZWw3X21uKQ0KDQojI21vZGVsMg0KIyMgcmVzMiA8LSByZXNpZHVhbHMobW9kZWwyKQ0KIyMgDQojIyByZXMyIDwtIGFzLmRhdGEuZnJhbWUocmVzMikNCiMjIA0KIyMgZ2dwbG90KHJlczIsIGFlcyhyZXMyKSkgKyBnZW9tX2hpc3RvZ3JhbShmaWxsID0gJ2dyZWVuJywgYWxwaGEgPSAwLjUpDQojIyANCiMjIHBsb3QobW9kZWwyKQ0KDQpJU1RfUlBQSV9NT0RFTCRwcmVkaWN0ZWQuSVNUX1BSQyA8LSBwcmVkaWN0KG1vZGVsN19tbiwgSVNUX1JQUElfTU9ERUwpDQpwbDFfbW4gPC0gSVNUX1JQUElfTU9ERUwgJT4lDQogICAgZ2dwbG90KGFlcyhJU1RfUFJDLCBwcmVkaWN0ZWQuSVNUX1BSQykpICsNCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC44MCkgKw0KICAgIHN0YXRfc21vb3RoKGFlcyhjb2xvdXIgPSAnYmxhY2snKSkgKw0KICAgIHhsYWIoJ0FjdHVhbCBIb3VzaW5nIFVuaXQgUHJpY2VzJykgKw0KICAgIHlsYWIoJ1ByZWRpY3RlZCBIb3VzaW5nIFVuaXQgUHJpY2VzJykgKw0KICAgIHRoZW1lX2J3KCkNCmdncGxvdGx5KHBsMV9tbikNCmBgYA0KDQoNCiMjIyMgRXJyb3JzXA0KDQpSb290IE1lYW4gU3F1YXJlIEVycm9yIG9mIE1vZGVsLTc6XA0KDQpgYGB7ciBFcnJvciBUZXJtcyB9DQplcnJvciA8LSBsb2cxMChJU1RfUlBQSV9NT0RFTCRJU1RfUFJDLUlTVF9SUFBJX01PREVMJHByZWRpY3RlZC5JU1RfUFJDKQ0Kcm1zZSA8LSBzcXJ0KG1lYW4oZXJyb3IpXjIpDQpkYXRhLmZyYW1lKGVycm9yKQ0KZGF0YS5mcmFtZShybXNlKQ0KYGBgDQpUcmllZCBmb3IgZWFjaCBvYnNlcnZhdGlvbnMgdG8gZXN0aW1hdGUgdGhlIHJlYWwgYW5kIHByZWRpY3RlZCB2YWx1ZSBpbiBNb2RlbC03DQpJbiB0aGlzIGNhc2UsIHVzaW5nIGxvZ2FyaXRobSBwcm9jZXNzIGZvciB0aGUgZXJyb3JzIGJlY2F1c2Ugb2YgdGhlIG1vZGVsIGluY2x1ZGUgSG91c2luZyBQcmljZSB3aXRoIExvZzEwLiANClNvIHRoaXMgZXJyb3JzIHNheSB1cyBkaWZmZXJlbmNlcyBiZXR3ZWVuIFJlYWwgSG91c2luZyBQcmljZSBhbmQgVGhlIG1vZGVsIHdoaWNoIGJ1aWx0IHRvIGV4cGxhaW4gaG91c2luZyBwcmljZS5cDQoNCiANCg0KDQoqKioNCg0KDQoNCiMjIyBUaW1lIFNlcmllc1wNCg0KKipBdXRvcmVncmVzc2l2ZSBJbnRlZ3JhdGVkIE1vdmluZyBBdmVyYWdlKipcDQoNCg0KDQpJbiBzdGF0aXN0aWNzIGFuZCBlY29ub21ldHJpYywgYW5kIGluIHBhcnRpY3VsYXIgaW4gdGltZSBzZXJpZXMgYW5hbHlzaXMsIGFuIGF1dG8gcmVncmVzc2l2ZSBpbnRlZ3JhdGVkIG1vdmluZyBhdmVyYWdlIChBUklNQSkgbW9kZWwgaXMgYSBnZW5lcmFsaXphdGlvbiBvZiBhbiBhdXRvIHJlZ3Jlc3NpdmUgbW92aW5nIGF2ZXJhZ2UgKEFSTUEpIG1vZGVsLiBCb3RoIG9mIHRoZXNlIG1vZGVscyBhcmUgZml0dGVkIHRvIHRpbWUgc2VyaWVzIGRhdGEgZWl0aGVyIHRvIGJldHRlciB1bmRlcnN0YW5kIHRoZSBkYXRhIG9yIHRvIHByZWRpY3QgZnV0dXJlIHBvaW50cyBpbiB0aGUgc2VyaWVzIChmb3JlY2FzdGluZykuIEFSSU1BIG1vZGVscyBhcmUgYXBwbGllZCBpbiBzb21lIGNhc2VzIHdoZXJlICoqZGF0YSBzaG93IGV2aWRlbmNlIG9mIG5vbi1zdGF0aW9uYXJpdHkqKiwgd2hlcmUgYW4gKippbml0aWFsIGRpZmZlcmVuY2luZyBzdGVwKiogKGNvcnJlc3BvbmRpbmcgdG8gdGhlICJpbnRlZ3JhdGVkIiBwYXJ0IG9mIHRoZSBtb2RlbCkgY2FuIGJlIGFwcGxpZWQgb25lIG9yIG1vcmUgdGltZXMgdG8gZWxpbWluYXRlIHRoZSBub24tc3RhdGlvbmFyeS5cDQoNClRoZSBBUiBwYXJ0IG9mIEFSSU1BIGluZGljYXRlcyB0aGF0IHRoZSBldm9sdmluZyB2YXJpYWJsZSBvZiBpbnRlcmVzdCBpcyAqKnJlZ3Jlc3NlZCBvbiBpdHMgb3duIGxhZ2dlZCoqIChpLmUuLCBwcmlvcikgdmFsdWVzLiBUaGUgTUEgcGFydCBpbmRpY2F0ZXMgdGhhdCB0aGUgKipyZWdyZXNzaW9uIGVycm9yKiogaXMgYWN0dWFsbHkgYSBsaW5lYXIgY29tYmluYXRpb24gb2YgKmVycm9yIHRlcm1zKiB3aG9zZSB2YWx1ZXMgb2NjdXJyZWQgY29udGVtcG9yYW5lb3VzbHkgYW5kIGF0IHZhcmlvdXMgdGltZXMgaW4gdGhlIHBhc3QuIFRoZSBJIChmb3IgImludGVncmF0ZWQiKSBpbmRpY2F0ZXMgdGhhdCB0aGUgZGF0YSB2YWx1ZXMgaGF2ZSBiZWVuIHJlcGxhY2VkIHdpdGggdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGVpciB2YWx1ZXMgYW5kIHRoZSBwcmV2aW91cyB2YWx1ZXMgKGFuZCB0aGlzIGRpZmZlcmVuY2UgcHJvY2VzcyBtYXkgaGF2ZSBiZWVuIHBlcmZvcm1lZCBtb3JlIHRoYW4gb25jZSkuIFRoZSBwdXJwb3NlIG9mIGVhY2ggb2YgdGhlc2UgZmVhdHVyZXMgaXMgdG8gbWFrZSB0aGUgbW9kZWwgZml0IHRoZSBkYXRhIGFzIHdlbGwgYXMgcG9zc2libGUuXA0KDQpOb24tc2Vhc29uYWwgQVJJTUEgbW9kZWxzIGFyZSBnZW5lcmFsbHkgZGVub3RlZCBBUklNQShwLGQscSkgd2hlcmUgcGFyYW1ldGVycyBwLCBkLCBhbmQgcSBhcmUgbm9uLW5lZ2F0aXZlIGludGVnZXJzLCBwIGlzIHRoZSBvcmRlciAobnVtYmVyIG9mIHRpbWUgbGFncykgb2YgdGhlIGF1dG8gcmVncmVzc2l2ZSBtb2RlbCwgZCBpcyB0aGUgZGVncmVlIG9mIGRpZmZlcmVuY2UgKHRoZSBudW1iZXIgb2YgdGltZXMgdGhlIGRhdGEgaGF2ZSBoYWQgcGFzdCB2YWx1ZXMgc3VidHJhY3RlZCksIGFuZCBxIGlzIHRoZSBvcmRlciBvZiB0aGUgbW92aW5nLWF2ZXJhZ2UgbW9kZWwuIFNlYXNvbmFsIEFSSU1BIG1vZGVscyBhcmUgdXN1YWxseSBkZW5vdGVkIEFSSU1BKHAsZCxxKShQLEQsUSltLCB3aGVyZSBtIHJlZmVycyB0byB0aGUgbnVtYmVyIG9mIHBlcmlvZHMgaW4gZWFjaCBzZWFzb24sIGFuZCB0aGUgdXBwZXJjYXNlIFAsRCxRIHJlZmVyIHRvIHRoZSBhdXRvIHJlZ3Jlc3NpdmUsIGRpZmZlcmVuY2UsIGFuZCBtb3ZpbmcgYXZlcmFnZSB0ZXJtcyBmb3IgdGhlIHNlYXNvbmFsIHBhcnQgb2YgdGhlIEFSSU1BIG1vZGVsLlwNCg0KKldoZW4gdHdvIG91dCBvZiB0aGUgdGhyZWUgdGVybXMgYXJlIHplcm9zLCB0aGUgbW9kZWwgbWF5IGJlIHJlZmVycmVkIHRvIGJhc2VkIG9uIHRoZSBub24temVybyBwYXJhbWV0ZXIsIGRyb3BwaW5nICJBUiIsICJJIiBvciAiTUEiIGZyb20gdGhlIGFjcm9ueW0gZGVzY3JpYmluZyB0aGUgbW9kZWwuIEZvciBleGFtcGxlLCBBUklNQSAoMSwwLDApIGlzIEFSKDEpLCBBUklNQSgwLDEsMCkgaXMgSSgxKSwgYW5kIEFSSU1BKDAsMCwxKSBpcyBNQSgxKS4qXA0KDQpBUklNQSBtb2RlbHMgY2FuIGJlIGVzdGltYXRlZCBmb2xsb3dpbmcgdGhlIEJveC1KZW5raW5zIGFwcHJvYWNoLlwNCg0KDQoNCioqVGhpcyBhbmFseXNpcyBoZWxwIHVzIHRvIHVuZGVyc3RhbmQgdGhlIGhvdXNpbmcgcHJpY2UgY2hhbmdlcyB3aWxsIGJlIGluIDYgbW9udGhzKipcDQoNCg0KDQogDQoNCiMjIyMgU2V0IFRoZSBMaWJyYXJpZXNcDQoNClNldHRpbmcgdGhlIGxpYnJhcmllcyB3aGljaCB3aWxsIHVzaW5nIG9uIGFuYWx5emUuXA0KDQpgYGB7ciBMaWJyYXJpZXMgfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShmb3JlY2FzdCkNCmxpYnJhcnkodHNlcmllcykNCmxpYnJhcnkoYXN0c2EpDQpsaWJyYXJ5KHJlYWRyKQ0KYGBgDQoNCg0KIyMjIyBEYXRhIEltcG9ydFwNCg0KVGhlIGRhdGEgaW5jbHVkZSBtb250aGx5IGNoYW5nZXMgb2YgdW5pdCBob3VzaW5nIHByaWNlcyBhdCBJc3RhbmJ1bFwNCg0KYGBge3IgRGF0YSBJbXBvcnQgfQ0KbGlicmFyeShyZWFkcikNCklTVF9VTlRQUkNfRlJDU1QgPC0gcmVhZF9jc3YoIklTVF9VTlRQUkNfRlJDU1QuY3N2IiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbF90eXBlcyA9IGNvbHMoREFURSA9IGNvbF9kYXRlKGZvcm1hdCA9ICIlZC4lbS4lWSIpKSkNCmhlYWQoSVNUX1VOVFBSQ19GUkNTVCkNCmBgYA0KDQoNCiMjIyMgU2hvdyBUaGUgRGlzdHJpYnV0aW9uIG9mIEhvdXNpbmcgUHJpY2UgSW5kZXhcIA0KDQpEaXN0cmlidXRpb24gb2YgTW9udGhseSBIb3VzaW5nIFByaWNlIENoYW5nZXM6XA0KDQpgYGB7ciBEaXN0cmlidXRpb24gb2YgSG91c2luZyBQcmljZSBDaGFuZ2VzICB9DQpnZ3Bsb3QoSVNUX1VOVFBSQ19GUkNTVCwgYWVzKERBVEUsIElTVF9QUkNfQ0cpKSArIA0KICAgIGdlb21fbGluZSgpICsgc2NhbGVfeF9kYXRlKCdZZWFycycpICArIA0KICAgIHlsYWIoIklzdGFuYnVsIEhvdXNpbmcgUHJpY2UgTW9udGhseSBDaGFuZ2VzIikgKw0KICAgICAgICAgICAgeGxhYigiIikNCmBgYA0KDQoNCiMjIyMgQ2xlYW4gVGhlIE91dGxpZXJzIHdpdGggVHNjbGVhblwNCg0KQ2xlYW5pbmcgdGhlIHRyZW5kIG9mIG1vbnRobHkgY2hhbmdlcyB0byBnZXQgbGluZWFyLCBoYW5kbGUgd2l0aCBleHRyZW1lIG91dGxpZXJzLg0KDQpgYGB7ciBDbGVhbiBUaGUgT3V0bGllcnMgfQ0KY291bnRfdHMgPSB0cyhJU1RfVU5UUFJDX0ZSQ1NUWywgYygnSVNUX1BSQ19DRycpXSkNCklTVF9VTlRQUkNfRlJDU1QkY2xlYW5fY250ID0gdHNjbGVhbihjb3VudF90cykNCmdncGxvdCgpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBJU1RfVU5UUFJDX0ZSQ1NULCBhZXMoeCA9IERBVEUsIHkgPSBjbGVhbl9jbnQpKSArIA0KICAgIHlsYWIoJ0NsZWFuZWQgSXN0YW5idWwgSG91c2luZyBQcmljZSBNb250aGx5IENoYW5nZXMnKQ0KYGBgDQoNCg0KIyMjIyBRdWFydGVybHkgYW5kIE1vbnRobHkgTW92aW5nIEF2ZXJhZ2VzXA0KDQpEaXZpZGUgaW50byBkYXRhIHNvbWUgZGlmZmVyZW50IHBlcmlvZHMgdG8gZm9yZWNhc3QgbW9yZSBhY2N1cmFjeS5cDQoNCmBgYHtyIE1vdmluZyBBdmVyYWdlcyB9DQpJU1RfVU5UUFJDX0ZSQ1NUJGNudF9tYTEgPSBtYShJU1RfVU5UUFJDX0ZSQ1NUJGNsZWFuX2NudCwgb3JkZXI9MSkNCklTVF9VTlRQUkNfRlJDU1QkY250X21hMiA9IG1hKElTVF9VTlRQUkNfRlJDU1QkY2xlYW5fY250LCBvcmRlcj0yKQ0KSVNUX1VOVFBSQ19GUkNTVCRjbnRfbWEzID0gbWEoSVNUX1VOVFBSQ19GUkNTVCRjbGVhbl9jbnQsIG9yZGVyPTMpDQpJU1RfVU5UUFJDX0ZSQ1NUJGNudF9tYTYgPSBtYShJU1RfVU5UUFJDX0ZSQ1NUJGNsZWFuX2NudCwgb3JkZXI9NikNCklTVF9VTlRQUkNfRlJDU1QkY250X21hMTIgPSBtYShJU1RfVU5UUFJDX0ZSQ1NUJGNsZWFuX2NudCwgb3JkZXI9MTIpDQoNCmdncGxvdCgpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBJU1RfVU5UUFJDX0ZSQ1NULCBhZXMoeCA9IERBVEUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gY2xlYW5fY250LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gIklzdGFuYnVsIEhvdXNpbmcgTW9udGhseSBDaGFuZ2VzIENsZWFuZWQiKSkgKw0KICBnZW9tX2xpbmUoZGF0YSA9IElTVF9VTlRQUkNfRlJDU1QsIGFlcyh4ID0gREFURSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBjbnRfbWExLCAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAiMSBNb250aGx5IE1vdmluZyBBdmVyYWdlIikpICArDQogIGdlb21fbGluZShkYXRhID0gSVNUX1VOVFBSQ19GUkNTVCwgYWVzKHggPSBEQVRFLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IGNudF9tYTIsICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9ICIyIE1vbnRobHkgTW92aW5nIEF2ZXJhZ2UiKSkgICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBJU1RfVU5UUFJDX0ZSQ1NULCBhZXMoeCA9IERBVEUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gY250X21hMywgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gIjMgTW9udGhseSBNb3ZpbmcgQXZlcmFnZSIpKSAgKw0KICBnZW9tX2xpbmUoZGF0YSA9IElTVF9VTlRQUkNfRlJDU1QsIGFlcyh4ID0gREFURSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBjbnRfbWE2LCAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAiNiBNb250aGx5IE1vdmluZyBBdmVyYWdlIikpICArDQogIGdlb21fbGluZShkYXRhID0gSVNUX1VOVFBSQ19GUkNTVCwgYWVzKHggPSBEQVRFLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IGNudF9tYTEyLCAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9ICIxMiBNb250aGx5IE1vdmluZyBBdmVyYWdlIikpICsNCiAgeWxhYignSXN0YW5idWwgUlBQSSBNb250aGx5IENoYW5nZXMnKQ0KYGBgDQoNCiMjIyMgRGVjb21wb3NlIC0gRm9yZWNhc3RpbmcgVGhlIERhdGFcDQoNCkRlY29tcG9zaW5nIGRhdGEgdG8gZ2V0IHJpZCBvZiBzZWFzb25hbGl0eS4gQ2hvb3NlcyB0aGUgZnJlcXVlbmN5IHR3by4NClRoaXMgbWVhbnMgQXV0byBSZWdyZXNzaXZlIFRlcm0gYW5kIE1vdmluZyBBdmFyYWdlcyBhY2NvcmRpbmcgdG8gdHdvIG1vbnRocy4gDQoNCmBgYHtyIERlY29tcG9zZSB9DQpjb3VudF9tYSA9IHRzKG5hLm9taXQoSVNUX1VOVFBSQ19GUkNTVCRjbnRfbWEyKSwgDQogICAgICAgICAgICAgIGZyZXF1ZW5jeT0yKQ0KZGVjb21wID0gc3RsKGNvdW50X21hLCANCiAgICAgICAgICAgICBzLndpbmRvdyA9ICJwZXJpb2RpYyIpDQpkZXNlYXNvbmFsX2NudCA8LSBzZWFzYWRqKGRlY29tcCkNCnBsb3QoZGVjb21wKQ0KYGBgDQoNCiogRGF0YSA6IFRoZSB0cmVuZCBpc24ndCBpbiBiYWxhbmNlIGFuZCB2ZXJ5IHZhcmlhYmxlIHRlcm0uDQoqIFNlYXNvbmFsaXR5OiBOb3QgaW4gc2Vhc29uYWxpdHkNCiogVHJlbmQ6IENoYW5nZXMgYXJlIGdvaW5nIGRvd24gZm9yIHRoZSBsYXN0IDUtNiBwZXJpb2RzLg0KKiBSZW1haW5kZXI6IFNob3cgdXMgdGhlIGxhZyBvZiBkYXRhLiBJbiB0aGUgMTZ0aCBwZXJpb2QuXA0KDQojIyMjIFN0YXRpb25hcml0eSAtIEFERiBUZXN0XA0KDQpgYGB7ciBBREYgVGVzdCB9DQphZGYudGVzdChjb3VudF9tYSwgDQogICAgICAgICBhbHRlcm5hdGl2ZSA9ICJzdGF0aW9uYXJ5IikNCmBgYA0KDQpOb3csIHRlc3RpbmcgbW9kZWwgd2l0aCBBREYgLSBBdWdtZW50ZWQgRGlja2V5IEZ1bGxlciBUZXN0LCBwLXZhbHVlIGJpZ2dlciB0aGFuIC4wNVwNCg0KDQojIyMjIEF1dG9jb3JyZWxhdGlvbiBhbmQgQ2hvb3NpbmcgTW9kZWwgT3JkZXIgKEFDRilcDQoNCkF1dG8gY29ycmVsYXRpb24sIGFsc28ga25vd24gYXMgKipzZXJpYWwgY29ycmVsYXRpb24qKiwgaXMgdGhlIGNvcnJlbGF0aW9uIG9mIGEgc2lnbmFsIHdpdGggYSBkZWxheWVkIGNvcHkgb2YgaXRzZWxmIGFzIGEgZnVuY3Rpb24gb2YgZGVsYXkuIEluZm9ybWFsbHksIGl0IGlzIHRoZSBzaW1pbGFyaXR5IGJldHdlZW4gb2JzZXJ2YXRpb25zIGFzIGEgZnVuY3Rpb24gb2YgdGhlICoqdGltZSBsYWcqKiBiZXR3ZWVuIHRoZW0uIFRoZSBhbmFseXNpcyBvZiBhdXRvIGNvcnJlbGF0aW9uIGlzIGEgbWF0aGVtYXRpY2FsIHRvb2wgZm9yIGZpbmRpbmcgcmVwZWF0aW5nIHBhdHRlcm5zLCBzdWNoIGFzIHRoZSBwcmVzZW5jZSBvZiBhIHBlcmlvZGljIHNpZ25hbCBvYnNjdXJlZCBieSBub2lzZSwgb3IgaWRlbnRpZnlpbmcgdGhlIG1pc3NpbmcgZnVuZGFtZW50YWwgZnJlcXVlbmN5IGluIGEgc2lnbmFsIGltcGxpZWQgYnkgaXRzIGhhcm1vbmljIGZyZXF1ZW5jaWVzLiBJdCBpcyBvZnRlbiB1c2VkIGluIHNpZ25hbCBwcm9jZXNzaW5nIGZvciBhbmFseXppbmcgZnVuY3Rpb25zIG9yIHNlcmllcyBvZiB2YWx1ZXMsIHN1Y2ggYXMgdGltZSBkb21haW4gc2lnbmFscy4NCg0KKkRpZmZlcmVudCBmaWVsZHMgb2Ygc3R1ZHkgZGVmaW5lIGF1dG9jb3JyZWxhdGlvbiBkaWZmZXJlbnRseSwgYW5kIG5vdCBhbGwgb2YgdGhlc2UgZGVmaW5pdGlvbnMgYXJlIGVxdWl2YWxlbnQuIEluIHNvbWUgZmllbGRzLCB0aGUgdGVybSBpcyB1c2VkIGludGVyY2hhbmdlYWJseSB3aXRoIGF1dG9jb3ZhcmlhbmNlLioNCg0KVW5pdCByb290IHByb2Nlc3NlcywgdHJlbmQgc3RhdGlvbmFyeSBwcm9jZXNzZXMsIGF1dG8gcmVncmVzc2l2ZSBwcm9jZXNzZXMsIGFuZCBtb3ZpbmcgYXZlcmFnZSBwcm9jZXNzZXMgYXJlIHNwZWNpZmljIGZvcm1zIG9mIHByb2Nlc3NlcyB3aXRoIGF1dG8gY29ycmVsYXRpb24uXA0KDQoNCmBgYHtyIEFDRi1QQUNGIH0NCiMjYXV0b2NvcnJlbGF0aW9uIA0KQWNmKGNvdW50X21hLCBtYWluID0iIiwgcGxvdCA9IFRSVUUpDQpQYWNmKGNvdW50X21hLCBtYWluID0iIiwgIHBsb3QgPSBUUlVFKQ0KI0FjZihjb3VudF9tYSwgbWFpbiA9IiIsIHBsb3QgPSBGQUxTRSkNCiNQYWNmKGNvdW50X21hLCBtYWluID0iIiwgIHBsb3QgPSBGQUxTRSkNCg0KYGBgDQoNClRoZXJlIGFyZSBubyBzdGF0aW9uYXJ5IGluIHRoZSBtb2RlbCwgTGFncyBhcmUga2VlcGluZyBkZWNyZWFzZSB1bnRpbGwgMTh0aCBwZXJpb2RzLlwNCg0KDQojIyMjIFR1bmUgVGhlIE1vZGVsXA0KDQpgYGB7ciBNb2RlbCBUdW5uaW5nIH0NCmNvdW50X2QxID0gZGlmZihkZXNlYXNvbmFsX2NudCwgZGlmZmVyZW5jZXMgPSAyKQ0KcGxvdChjb3VudF9kMSkNCmFkZi50ZXN0KGNvdW50X2QxLCBhbHRlcm5hdGl2ZSA9ICJzdGF0aW9uYXJ5IiApDQpgYGANCg0KSWYgdGhlIHAgdmFsdWUgd2FzIGJpZ2dlciB0aGFuIDAuMDUsIERpZmZlcmVuY2VzIHNob3VsZCBiZSB1c2UgYWdhaW4uIFRoZSBtb2RlbCdzIHAtdmFsdWUgfiAuMDFcDQoNClRoaXMgcHJvY2VzcyB1c2luZyBlcnJvcnMgdG8gZm9yZWNhc3QgcHJldmlvdXMgcGVyaW9kcy4NCg0KDQpgYGB7ciB9DQojIyBjb3VudF9kMiA9IGRpZmYoY291bnRfZDEsIGRpZmZlcmVuY2VzID0gMSkNCiMjIHBsb3QoY291bnRfZDIpDQojIyBhZGYudGVzdChjb3VudF9kMiwgYWx0ZXJuYXRpdmUgPSAic3RhdGlvbmFyeSIgKQ0KYGBgDQoNCg0KYGBge3IgQUNGLVBBQ0YyIH0NCkFjZihjb3VudF9kMSwgDQogICAgbWFpbiA9ICJBQ0YgZm9yIERpZmZlcmVuY2VkIFNlcmllcyIpDQpQYWNmKGNvdW50X2QxLCANCiAgICAgbWFpbiA9ICJQQUNGIGZvciBEaWZmZXJlbmNlZCBTZXJpZXMiKQ0KI0FjZihjb3VudF9kMSwgDQojICAgIG1haW4gPSAiQUNGIGZvciBEaWZmZXJlbmNlZCBTZXJpZXMiLCBwbG90ID0gRkFMU0UpDQojUGFjZihjb3VudF9kMSwgDQojICAgICBtYWluID0gIlBBQ0YgZm9yIERpZmZlcmVuY2VkIFNlcmllcyIsIHBsb3QgPSBGQUxTRSkNCmBgYA0KDQpMYWdzIGNhbiBiZSBvYnNlcnZlZCBpbiAzcmQgbW9udGhzIGJlY2F1c2Ugb2YgdGhlIG1vZGVsIGFycmF5IG9yZGVyIGlzIDMuIFRvIGp1c3RpZnkgdGhlIG1vZGVsIGxhZyBtYXggc2hvdWxkIGJlIDMuIEF0IDl0aCBtb250aCdzIGxhZyBpc24ndCBpbiB0cnVzdCBsaW5lLiBGaXR0aW5nIGFuZCBBdXRvYXJpbWEgc2hvdWxkIGJlIHRyeS5cDQoNCg0KIA0KDQojIyMjIEZpdHRpbmcgYW4gQVJJTUEgTW9kZWxcDQoNCmBgYHtyIEZpdHRpbmcgQXV0b0FyaW1hIH0NCmF1dG8uYXJpbWEoZGVzZWFzb25hbF9jbnQsIHNlYXNvbmFsID0gRkFMU0UpDQpgYGANCg0KKipBdXRvIGFyaW1hIHNheSB0byBtb2RlbCB1c2UgQXV0byBSZWdyZXNzaXZlIFRlcm0gYW5kIE1vdmluZyBBdmVyYWdlIFR3bywgRGlmZmVyZW5jZSBwZXJpb2QgaXMgb25lLioqXA0KDQogDQojIyMjIEV2YWx1YXRlIGFuZCBJdGVyYXRlXA0KDQpgYGB7ciBFdmFsdWF0ZS1JdGVyYXRlIH0NCmZpdDEgPC0gYXV0by5hcmltYShkZXNlYXNvbmFsX2NudCwgDQogICAgICAgICAgICAgICAgICAgc2Vhc29uYWwgPSBGQUxTRSkNCnRzZGlzcGxheShyZXNpZHVhbHMoZml0MSksIGxhZy5tYXggPSAxOCwgDQogICAgICAgICAgbWFpbiA9ICIoMiwxLDIpIE1vZGVsIFJlc2lkdWFscyIpDQpgYGANCg0KDQpgYGB7ciB9DQojZml0MiA9IGFyaW1hKGRlc2Vhc29uYWxfY250LCBvcmRlciA9IGMoMSwxLDEpKQ0KI2ZpdDINCiN0c2Rpc3BsYXkocmVzaWR1YWxzKGZpdDIpLCBsYWcubWF4ID0gMTIsIG1haW4gPSJTZWFzb25hbCBNb2RlbCBSZXNpZHVhbHMiKQ0KYGBgDQoNCmBgYHtyIEZvcmVjYXN0IFBsb3QgfQ0KZmNhc3QgPC0gZm9yZWNhc3QoZml0MSwgaCA9IDYpDQpwbG90KGZjYXN0KQ0KYGBgDQoNCmBgYHtyIERlc2Vhc29uYWwgIH0NCmhvbGQgPC0gd2luZG93KHRzKGRlc2Vhc29uYWxfY250KSwgc3RhcnQgPSA2MCkNCmZpdF9ub19ob2xkb3V0ID0gYXJpbWEodHMoZGVzZWFzb25hbF9jbnRbLWMoNzg6ODkpXSksIA0KICAgICAgICAgICAgICAgICAgICAgICBvcmRlciA9IGMoMiwxLDIpKQ0KZmNhc3Rfbm9faG9sZG91dCA8LSBmb3JlY2FzdChmaXRfbm9faG9sZG91dCwgaCA9IDYpDQpwbG90KGZjYXN0X25vX2hvbGRvdXQsIG1haW4gPSAiIikNCmxpbmVzKHRzKGRlc2Vhc29uYWxfY250KSkNCmBgYA0KDQpgYGB7ciBTZWFzb25hbGl0eSB9DQpmaXRfd19zZWFzb25hbGl0eSA9IGF1dG8uYXJpbWEoZGVzZWFzb25hbF9jbnQsIHNlYXNvbmFsPVRSVUUpDQpmaXRfd19zZWFzb25hbGl0eQ0KYGBgDQoNCg0KIyMjIyBGb3JlY2FzdCBUaGUgSXN0YW5idWwgSG91c2luZyBQcmljZSBDaGFuZ2VzXA0KDQoNCiANCg0KKipBY3R1YWwgVmFsdWUgb2YgVGhlIFByaWNlIEluZGV4KipcDQoNCg0KDQoqKkRBVEUqKiAgICAgIHwgKipJU1QgUlBQSSoqIHwgKipDSEFOR0UqKiB8ICoqVU5JVCBQUklDRVMqKiAgIHwgKipVTklUIFBSSUNFIENIQU5HRSoqDQotLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLXwgLS0tLS0tLS0tLS0tLS0tLS0tLQ0KMS4wMS4yMDE5ICAgICB8IDEwMC4xNSAgICAgICB8IC0xLjg0ICAgICAgfCA0OTAwLjE1ICAgICAgICAgICB8IC0zLjY2DQoyLjAyLjIwMTkgICAgIHwJOTkuNjMgICAgICAgIHwgLTAuNTIgICAgICB8IDQ3MDIuMDMgICAgICAgICAgIHwgLTQuMDQNCjMuMDMuMjAxOSAgICAgfCA5OS4zNCAgICAgICAgfCAtMC4yOSAgICAgIHwgNDY1Ny41OSAgICAgICAgICAgfCAtMC45NQ0KDQoNCg0KIA0KDQpgYGB7ciBGb3JlY2FzdCB9DQpzZWFzX2ZjYXN0IDwtIGZvcmVjYXN0KGZpdF93X3NlYXNvbmFsaXR5LCBoPTEyKQ0KcGxvdChzZWFzX2ZjYXN0KQ0Kc3VtbWFyeShzZWFzX2ZjYXN0KQ0KYGBgDQoNCg0KXA0KDQoNCioqKg0KDQoNClwNCg0KDQojIyMgVGhlIFJlc3VsdFwNCg0KDQoNClRoZSByZXN1bHQgb2YgdGhlIHN0dWR5ICJIb3VzaW5nIFByaWNlcyBpbiBJc3RhbmJ1bCIgYXJlIG1vcmUgaW1wb3NlIGJ5ICoqQ29uc3VtZXIgYW5kIFByb2R1Y2VyIEluZGV4IHJlbGF0ZWQgd2l0aCBSZW50LCBVU0QgQ3VycmVuY3kgUmF0ZSwgQ29uc3RydWN0aW9uIFBlcm1pdHMgYW5kIEZvcmVpZ25lciBTYWxlcyoqLiBTb21lIEluZGV4IGFuZCBSYXRlcyBkaXJlY3RseSBhZmZlY3RpbmcgUHJpY2VzJlNhbGVzLiBUaGUgZmluYWwgbW9kZWwgYmVsb3cgd2l0aCB0aGUgZXF1YXRpb246XA0KDQpcDQoNCg0KKioqDQoNCg0KJCQgbG9nMTAoSG91c2luZ1ByaWNlKSA9IDAuMDd4bG9nMTAoRlJHTlJTTCkrMC4wMDN4UmVudENQSS0wLjA1eFVTRFJhdGUrMC4wN3hsb2cxMChDTlNUUFJNVCkrMi4xNzUgJCRcDQoNCg0KDQoqKioNCg0KDQoNCg0KJCQgbG9nMTAoU2FsZXMpID0gMC4xOTd4bG9nMTAoRlJHTlJTTCktMC4wNDV4TUdSVC0wLjAwMDd4VFJQUEkrNC4wNjQgJCRcDQoNCg0KDQoqKioNCg0KDQoNClJlZ3Jlc3Npb24gYW5hbHlzaXMgcHJvdmVkIHRoYXQgdGhlIG90aGVyIGluZGVwZW5kZW50IHZhcmlhYmxlcyBtYXkgYWZmZWN0aW5nIGxlc3MgdGhhbiBjb25zdW1lciBhbmQgcHJvY3VkZXIgaW5kZXguIA0KVGltZSBTZXJpZXMgQW5hbHlzaXMgYWxzbyBwcm92ZWQgdGhhdCBIb3VzaW5nIE1hcmtldCBpbiBJc3RhbmJ1bCB3aWxsIGJlIG5lZ2F0aXZlIGdyb3d0aCBmb3IgNiBtb250aHMgYXMgd2VsbCB3aWxsIGJlIGRlY3JlYXNpbmcgVGhlIEhvdXNpbmcgUHJpY2VzIGZvciA2IG1vbnRocy5cDQoNCg0KXA0KDQoNCioqKg0KDQoNClwNCg0KDQoNCiMjIyBSZWZlcmVuY2VzXA0KDQoxLiBMaW5lYXIgUmVncmVzc2lvbiwgU2VsdmEgUHJhYmhha2FyYW4NCjIuIExpbmVhciBSZWdyZXNzaW9uIHdpdGggQm9zdG9uIEhvdXNpbmcgRGF0YSBzZXQsIFN1a2VzaCBLdW1hciBQYWJiYQ0KMy4gSW50cm9kdWN0aW9uIHRvIEZvcmVjYXN0aW5nIHdpdGggQVJJTUEgaW4gUiwgUnVzbGFuYSBEYWxpbmluYQ0KNC4gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQXV0b3JlZ3Jlc3NpdmVfaW50ZWdyYXRlZF9tb3ZpbmdfYXZlcmFnZQ0KNS4gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQXV0b2NvcnJlbGF0aW9uXA0KNi4gT3ZlcnZpZXcgT2YgVGhlIFJlYWwgRXN0YXRlIEFuZCBIb3VzaW5nIEluZHVzdHJ5ICwgTWF5IDIwMTgNCjcuIEtheWEsIEFzbMSxICwg4oCcRGV0ZXJtaW5pbmcgb2YgVGhlIEZhY3RvcnMgQWZmZWN0cyBIb3VzaW5nIFByaWNlIGluIFR1cmtleSB3aXRoIEhlZG9uaWMgUHJpY2UgTW9kZWwg4oCdLCBDQlJUIEV4cGVydGlzZSBRdWFsaWZpY2F0aW9uIFRoZXNpcyBVbnB1Ymxpc2hlZCxBbmthcmEgLCAyMDEyDQoNClwNCg0KDQoqKioNCg0KDQpcDQo=